Standard Tokenizer
The standard tokenizer in Zilliz Cloud groups consecutive Unicode letters and numeric characters into tokens, splitting at other characters.
Tokenization rules
The standard tokenizer keeps consecutive characters that belong to the following sets in the same token:
-
ASCII characters: letters
A-Zanda-z, and digits0-9. -
Non-ASCII characters: characters with the Unicode
Alphabeticproperty or one of the numeric general categoriesNd,Nl, orNo.
| Unicode property or category | Meaning | Examples of characters retained in tokens |
|---|---|---|
Alphabetic | Letters across writing systems, including Chinese characters and Japanese kana, and some combining marks | 中文测试, カタカナ |
Nd (Decimal_Number) | Decimal digits | ٣ |
Nl (Letter_Number) | Letter-like numeric characters | Ⅷ |
No (Other_Number) | Other numeric characters, such as circled numbers, superscripts, and fractions | ①²¾ |
Characters outside these sets separate tokens and are discarded. These include whitespace, punctuation, underscores (_), hyphens (-), apostrophes ('), and symbols such as +, $, and 😀. Consecutive separators do not produce empty tokens.
Character classification follows Rust's char::is_alphanumeric(). For property definitions, see Unicode Standard Annex #44. The complete Unicode 17.0 character lists are available in DerivedCoreProperties.txt for Alphabetic and DerivedGeneralCategory.txt for Nd, Nl, and No. Character membership depends on the Unicode data used by the deployed version.
The following examples use {"tokenizer": "standard"} with no filters. The tokenizer preserves letter case and does not segment continuous Chinese text into individual words.
| Input | Output tokens |
|---|---|
foo_bar-can't😀123 | ["foo", "bar", "can", "t", "123"] |
中文测试 | ["中文测试"] |
version①.¾ | ["version①", "¾"] |
Hello,World! | ["Hello", "World"] |
Configuration
To configure an analyzer using the standard tokenizer, set tokenizer to standard in analyzer_params.
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
analyzer_params = {
"tokenizer": "standard",
}
import java.util.HashMap;
import java.util.Map;
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", "standard");
analyzerParams := map[string]any{"tokenizer": "standard"}
let analyzer_params = serde_json::json!({
"tokenizer": "standard"
});
nlohmann::json analyzer_params = {
{"tokenizer", "standard"}
};
const analyzer_params = {
"tokenizer": "standard",
};
# restful
analyzerParams='{
"tokenizer": "standard"
}'
The standard tokenizer can work in conjunction with one or more filters. For example, the following code defines an analyzer that uses the standard tokenizer and lowercase filter:
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
analyzer_params = {
"tokenizer": "standard",
"filter": ["lowercase"]
}
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("lowercase"));
analyzerParams := map[string]any{"tokenizer": "standard", "filter": []any{"lowercase"}}
let analyzer_params = serde_json::json!({
"tokenizer": "standard",
"filter": ["lowercase"]
});
nlohmann::json analyzer_params = {
{"tokenizer", "standard"},
{"filter", {"lowercase"}}
};
const analyzer_params = {
"tokenizer": "standard",
"filter": ["lowercase"]
};
# restful
analyzerParams='{
"tokenizer": "standard",
"filter": [
"lowercase"
]
}'
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": ["lowercase"]
}
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("lowercase"));
analyzerParams := map[string]any{"tokenizer": "standard", "filter": []any{"lowercase"}}
let analyzer_params = serde_json::json!({
"tokenizer": "standard",
"filter": ["lowercase"]
});
nlohmann::json analyzer_params = {
{"tokenizer", "standard"},
{"filter", {"lowercase"}}
};
const analyzer_params = {
"tokenizer": "standard",
"filter": ["lowercase"]
};
# restful
analyzerParams='{
"tokenizer": "standard",
"filter": [
"lowercase"
]
}'
Verification using run_analyzer
- Python
- Java
- Go
- Rust
- C++
- NodeJS
- cURL
from pymilvus import (
MilvusClient,
)
client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)
# Sample text to analyze
sample_text = "The Milvus vector database is built for scale!"
# 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")
.token("YOUR_CLUSTER_TOKEN")
.build();
MilvusClientV2 client = new MilvusClientV2(config);
List<String> texts = new ArrayList<>();
texts.add("The Milvus vector database is built for scale!");
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"
)
ctx := context.Background()
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{"The Milvus vector database is built for scale!"}
option := milvusclient.NewRunAnalyzerOption(texts...).
WithAnalyzerParams(analyzerParams)
result, err := client.RunAnalyzer(ctx, option)
if err != nil {
fmt.Println(err.Error())
// handle error
}
fmt.Println(result)
use milvus::v2::prelude::*;
let config = ConnectConfig::new().uri("YOUR_CLUSTER_ENDPOINT").token("YOUR_CLUSTER_TOKEN");
let client = ClientV2::new(&config).await?;
let sample_text = "The Milvus vector database is built for scale!";
let result = client
.run_analyzer(
RunAnalyzerRequest::builder()
.texts(vec![sample_text])
.analyzer_params(analyzer_params)
.build()?,
)
.await?;
println!("Standard analyzer output: {:?}", result);
#include "milvus/MilvusClientV2.h"
auto client = milvus::MilvusClientV2::Create();
milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
std::string text = "The Milvus vector database is built for scale!";
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", token: "YOUR_CLUSTER_TOKEN" });
const sampleText = "The Milvus vector database is built for scale!";
const result = await client.runAnalyzer({
text: sampleText,
analyzer_params,
});
console.log("Standard analyzer output:", result);
export CLUSTER_ENDPOINT="YOUR_CLUSTER_ENDPOINT"
export TOKEN="YOUR_CLUSTER_TOKEN"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/common/run_analyzer" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"text": ["The Milvus vector database is built for scale!"],
"analyzerParams": "{\"tokenizer\": \"standard\", \"filter\": [\"lowercase\"]}"
}'
Expected output
['the', 'milvus', 'vector', 'database', 'is', 'built', 'for', 'scale']