Stemmer
The stemmer filter reduces words to their base or root form (known as stemming), making it easier to match words with similar meanings across different inflections. The stemmer filter supports multiple languages, allowing for effective search and indexing in various linguistic contexts.
Configuration
The stemmer filter is a custom filter in Zilliz Cloud. To use it, specify "type": "stemmer" in the filter configuration, along with a language parameter to select the desired language for stemming.
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
analyzer_params = {
"tokenizer": "standard",
"filter":[{
"type": "stemmer", # Specifies the filter type as stemmer
"language": "english", # Sets the language for stemming to English
}],
}
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", "standard");
analyzerParams.put("filter",
Collections.singletonList(
new HashMap<String, Object>() {{
put("type", "stemmer");
put("language", "english");
}}
)
);
analyzerParams := map[string]any{"tokenizer": "standard",
"filter": []any{map[string]any{
"type": "stemmer",
"language": "english",
}}}
use serde_json::json;
let analyzer_params = json!({
"tokenizer": "standard",
"filter": [
{ "type": "stemmer", "language": "english" }
]
});
nlohmann::json analyzer_params = {
{"tokenizer", "standard"},
{"filter", {
{
{"type", "stemmer"},
{"language", "english"}
}
}}
};
const analyzer_params = {
"tokenizer": "standard",
"filter":[{
"type": "stemmer", // Specifies the filter type as stemmer
"language": "english",
}],
};
# restful
analyzerParams='{
"tokenizer": "standard",
"filter": [
{
"type": "stemmer",
"language": "english"
}
]
}'
The stemmer filter accepts the following configurable parameters.
| Parameter | Description |
|---|---|
language | Specifies the language for the stemming process. Supported languages include: "arabic", "danish", "dutch", "english", "finnish", "french", "german", "greek", "hungarian", "italian", "norwegian", "portuguese", "romanian", "russian", "spanish", "swedish", "tamil", "turkish" |
The stemmer filter operates on the terms generated by the tokenizer, so it must be used in combination with a tokenizer.
After defining analyzer_params, you can apply them to a VARCHAR field when defining a collection schema. This allows Zilliz Cloud to process the text in that field using the specified analyzer for efficient tokenization and filtering. For details, refer to Example use.
Examples
Before applying the analyzer configuration to your collection schema, verify its behavior using the run_analyzer method.
Analyzer configuration
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
analyzer_params = {
"tokenizer": "standard",
"filter":[{
"type": "stemmer", # Specifies the filter type as stemmer
"language": "english", # Sets the language for stemming to English
}],
}
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", "standard");
analyzerParams.put("filter",
Collections.singletonList(
new HashMap<String, Object>() {{
put("type", "stemmer");
put("language", "english");
}}
)
);
analyzerParams := map[string]any{"tokenizer": "standard",
"filter": []any{map[string]any{
"type": "stemmer",
"language": "english",
}}}
use serde_json::json;
let analyzer_params = json!({
"tokenizer": "standard",
"filter": [
{ "type": "stemmer", "language": "english" }
]
});
nlohmann::json analyzer_params = {
{"tokenizer", "standard"},
{"filter", {
{
{"type", "stemmer"},
{"language", "english"}
}
}}
};
const analyzer_params = {
"tokenizer": "standard",
"filter":[{
"type": "stemmer", // Specifies the filter type as stemmer
"language": "english",
}],
};
# restful
analyzerParams='{
"tokenizer": "standard",
"filter": [
{
"type": "stemmer",
"language": "english"
}
]
}'
Verification using run_analyzer
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
from pymilvus import (
MilvusClient,
)
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# Sample text to analyze
sample_text = "running runs looked ran runner"
# Run the standard analyzer with the defined configuration
result = client.run_analyzer(sample_text, analyzer_params)
print("Standard analyzer output:", result)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.RunAnalyzerReq;
import io.milvus.v2.service.vector.response.RunAnalyzerResp;
import java.util.ArrayList;
import java.util.List;
ConnectConfig config = ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build();
MilvusClientV2 client = new MilvusClientV2(config);
List<String> texts = new ArrayList<>();
texts.add("running runs looked ran runner");
RunAnalyzerResp resp = client.runAnalyzer(RunAnalyzerReq.builder()
.texts(texts)
.analyzerParams(analyzerParams)
.build());
List<RunAnalyzerResp.AnalyzerResult> results = resp.getResults();
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v3/milvusclient"
)
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "YOUR_CLUSTER_ENDPOINT",
APIKey: "YOUR_CLUSTER_TOKEN",
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
texts := []string{"running runs looked ran runner"}
option := milvusclient.NewRunAnalyzerOption(texts...).
WithAnalyzerParams(analyzerParams)
result, err := client.RunAnalyzer(ctx, option)
if err != nil {
fmt.Println(err.Error())
// handle error
}
use milvus::v2::prelude::*;
let response = client
.run_analyzer(
RunAnalyzerRequest::builder()
.texts(["running runs looked ran runner"])
.analyzer_params(analyzer_params)
.build()?,
)
.await?;
for result in response.results() {
for token in result.get_tokens() {
println!("Standard analyzer output: {}", token.get_text());
}
}
#include "milvus/MilvusClientV2.h"
auto client = milvus::MilvusClientV2::Create();
milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
std::string text = "running runs looked ran runner";
auto request = milvus::RunAnalyzerRequest()
.AddText(text)
.WithAnalyzerParams(analyzer_params);
milvus::RunAnalyzerResponse response;
status = client->RunAnalyzer(request, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
import { MilvusClient } from '@zilliz/milvus2-sdk-node';
const client = new MilvusClient({
address: 'YOUR_CLUSTER_ENDPOINT',
});
const sample_text = 'running runs looked ran runner';
const result = await client.runAnalyzer({
text: sample_text,
analyzer_params,
});
const tokens = result.results.flatMap(r => r.tokens.map(t => t.token));
console.log('Standard analyzer output:', tokens);
curl --request POST \
--url "YOUR_CLUSTER_ENDPOINT/v2/vectordb/common/run_analyzer" \
--header "Authorization: Bearer YOUR_CLUSTER_TOKEN" \
--header "Content-Type: application/json" \
--data-raw '{
"analyzerParams": "{\"tokenizer\": \"standard\", \"filter\": [{\"type\": \"stemmer\", \"language\": \"english\"}]}",
"text": ["running runs looked ran runner"]
}'
Expected output
['run', 'run', 'look', 'ran', 'runner']