Jieba
Der Tokenizer „ jieba “ verarbeitet chinesischen Text, indem er ihn in einzelne Wörter zerlegt.
Der Tokenizer „ jieba “ behält Satzzeichen in der Ausgabe als separate Token bei. So wird beispielsweise aus „ "你好!世界。" “ die Zeichenfolge „ ["你好", "!", "世界", "。"] “. Um diese eigenständigen Satzzeichen-Token zu entfernen, verwenden Sie den removepunct Filter.
Konfiguration
Milvus unterstützt zwei Konfigurationsansätze für den „ jieba “-Tokenizer: eine einfache Konfiguration und eine benutzerdefinierte Konfiguration.
Einfache Konfiguration
Bei der einfachen Konfiguration müssen Sie lediglich den Tokenizer auf „ "jieba" “ setzen. Beispiel:
# Simple configuration: only specifying the tokenizer name
analyzer_params = {
"tokenizer": "jieba", # Use the default settings: dict=["_default_"], mode="search", hmm=True
}
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", "jieba");
analyzerParams := map[string]any{"tokenizer": "jieba"}
use serde_json::json;
let analyzer_params = json!({"tokenizer": "jieba"});
nlohmann::json analyzer_params = {
{"tokenizer", "jieba"}
};
const analyzer_params = {
"tokenizer": "jieba",
};
// Simple configuration: only specifying the tokenizer name
var analyzerParams = new Dictionary<string, object>
{
["tokenizer"] = "jieba" // Use the default settings: dict=["_default_"], mode="search", hmm=True
};
# restful
analyzerParams='{
"tokenizer": "jieba"
}'
Diese einfache Konfiguration entspricht der folgenden benutzerdefinierten Konfiguration:
# Custom configuration equivalent to the simple configuration above
analyzer_params = {
"tokenizer": { # Tokenizer configuration
"type": "jieba", # Tokenizer type, fixed as "jieba"
"dict": ["_default_"], # Use the default dictionary
"mode": "search", # Use search mode for improved recall (see mode details below)
"hmm": True # Enable HMM for probabilistic segmentation
}
}
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", new HashMap<String, Object>() {{
put("type", "jieba");
put("dict", Collections.singletonList("_default_"));
put("mode", "search");
put("hmm", true);
}});
analyzerParams := map[string]any{
"tokenizer": map[string]any{
"type": "jieba",
"dict": []any{"_default_"},
"mode": "search",
"hmm": true,
},
}
use serde_json::json;
let analyzer_params = json!({
"tokenizer": {
"type": "jieba",
"dict": ["_default_"],
"mode": "search",
"hmm": true
}
});
nlohmann::json analyzer_params = {
{"tokenizer", {
{"type", "jieba"},
{"dict", {"_default_"}},
{"mode", "search"},
{"hmm", true}
}}
};
const analyzer_params = {
tokenizer: {
type: "jieba",
dict: ["_default_"],
mode: "search",
hmm: true,
},
};
// Custom configuration equivalent to the simple configuration above
var analyzerParams = new Dictionary<string, object>
{
["tokenizer"] = new Dictionary<string, object> // Tokenizer configuration
{
["type"] = "jieba", // Tokenizer type, fixed as "jieba"
["dict"] = new[] { "_default_" }, // Use the default dictionary
["mode"] = "search", // Use search mode for improved recall (see mode details below)
["hmm"] = true // Enable HMM for probabilistic segmentation
}
};
# restful
analyzerParams='{
"tokenizer": {
"type": "jieba",
"dict": ["_default_"],
"mode": "search",
"hmm": true
}
}'
Einzelheiten zu den Parametern finden Sie unter „Benutzerdefinierte Konfiguration“.
Benutzerdefinierte Konfiguration
Für mehr Kontrolle können Sie eine benutzerdefinierte Konfiguration vornehmen, mit der Sie ein benutzerdefiniertes Wörterbuch festlegen, den Segmentierungsmodus auswählen und das Hidden-Markov-Modell (HMM) aktivieren oder deaktivieren können. Beispiel:
# Custom configuration with user-defined settings
analyzer_params = {
"tokenizer": {
"type": "jieba", # Fixed tokenizer type
"dict": ["customDictionary"], # Custom dictionary list; replace with your own terms
"mode": "exact", # Use exact mode (non-overlapping tokens)
"hmm": False # Disable HMM; unmatched text will be split into individual characters
}
}
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", new HashMap<String, Object>() {{
put("type", "jieba");
put("dict", Arrays.asList("customDictionary"));
put("mode", "exact");
put("hmm", false);
}});
analyzerParams := map[string]any{
"tokenizer": map[string]any{
"type": "jieba",
"dict": []string{"customDictionary"},
"mode": "exact",
"hmm": false,
},
}
use serde_json::json;
let analyzer_params = json!({
"tokenizer": {
"type": "jieba",
"dict": ["customDictionary"],
"mode": "exact",
"hmm": false
}
});
nlohmann::json analyzer_params = {
{"tokenizer", {
{"type", "jieba"},
{"dict", {"customDictionary"}},
{"mode", "exact"},
{"hmm", false}
}}
};
const analyzer_params = {
tokenizer: {
type: "jieba",
dict: ["customDictionary"],
mode: "exact",
hmm: false,
},
};
// Custom configuration with user-defined settings
var analyzerParams = new Dictionary<string, object>
{
["tokenizer"] = new Dictionary<string, object>
{
["type"] = "jieba", // Fixed tokenizer type
["dict"] = new[] { "customDictionary" }, // Custom dictionary list; replace with your own terms
["mode"] = "exact", // Use exact mode (non-overlapping tokens)
["hmm"] = false // Disable HMM; unmatched text will be split into individual characters
}
};
# restful
analyzerParams='{
"tokenizer": {
"type": "jieba",
"dict": ["customDictionary"],
"mode": "exact",
"hmm": false
}
}'
Parameter |
Beschreibung |
Standardwert |
|---|---|---|
|
Der Typ des Tokenizers. Dieser ist fest auf „ |
|
|
Eine Liste von Wörterbüchern, die der Analysator als Vokabularquelle lädt. Integrierte Optionen:
|
|
|
Der Segmentierungsmodus. Mögliche Werte:
|
|
|
Ein boolescher Schalter, der angibt, ob das Hidden-Markov-Modell (HMM) für die probabilistische Segmentierung von Wörtern aktiviert werden soll, die nicht im Wörterbuch enthalten sind. |
|
Um ein großes benutzerdefiniertes Vokabular aus einer externen Datei zu laden, anstatt es über ` dict` einzubinden, lesen Sie den Abschnitt „Benutzerdefinierte Konfiguration mit einer Wörterbuchdatei“ weiter unten.
Nachdem Sie „ analyzer_params “ definiert haben, können Sie diese bei der Definition eines Sammlungsschemas auf ein Feld vom Typ „ VARCHAR “ anwenden. Dadurch kann Milvus den Text in diesem Feld mit dem angegebenen Analysator verarbeiten, um eine effiziente Tokenisierung und Filterung zu gewährleisten. Weitere Informationen finden Sie unter „Anwendungsbeispiel“.
Bei umfangreichen benutzerdefinierten Vokabularen – Fachglossaren, Produktterminologie oder Listen mit Eigennamen – speichern Sie die Wörter in einer Datei und registrieren Sie die Datei als Remote-Dateiressource. Verweisen Sie anschließend über den Parameter „ extra_dict_file “ vom Tokenizer aus darauf. Der Analysator lädt diese Wörter zusätzlich zum integrierten Wörterbuch in sein Vokabular.
Die Datei ist einfacher UTF-8-Text mit einem Begriff pro Zeile. Zum Beispiel:
结巴分词器
向量数据库
Laden Sie die Datei in den Objektspeicher hoch, für dessen Verwendung Ihr Milvus-Cluster konfiguriert ist, und registrieren Sie sie anschließend:
from pymilvus import MilvusClient
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
# Register the uploaded file under a name you'll reference from analyzer configs.
client.add_file_resource(
name="zh_terms",
path="file/zh_terms.txt", # full S3 object key, including the rootPath prefix
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.utility.request.AddFileResourceReq;
ConnectConfig config = ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build();
MilvusClientV2 client = new MilvusClientV2(config);
client.addFileResource(AddFileResourceReq.builder()
.name("zh_terms")
.path("file/zh_terms.txt")
.build());
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v3/milvusclient"
)
ctx := context.Background()
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "http://localhost:19530",
APIKey: "root:Milvus",
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
err = client.AddFileResource(ctx, milvusclient.NewAddFileResourceOption("zh_terms", "file/zh_terms.txt"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
use milvus::v2::prelude::*;
let config = ConnectConfig::new().uri("http://localhost:19530").token("root:Milvus");
let client = ClientV2::new(&config).await?;
client.add_file_resource(AddFileResourceRequest::builder()
.name("zh_terms")
.path("file/zh_terms.txt")
.build()?).await?;
#include "milvus/MilvusClientV2.h"
#include <iostream>
auto client = milvus::MilvusClientV2::Create();
milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
milvus::AddFileResourceRequest add_file_request;
add_file_request.WithName("zh_terms");
add_file_request.WithPath("file/zh_terms.txt");
status = client->AddFileResource(add_file_request);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
import { MilvusClient } from '@zilliz/milvus2-sdk-node';
const client = new MilvusClient({
address: 'http://localhost:19530',
token: 'root:Milvus',
});
await client.addFileResource({
name: "zh_terms",
path: "file/zh_terms.txt",
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Utility;
using var client = new MilvusClientV2(new ConnectConfig
{
Uri = "http://localhost:19530",
ApiKey = "root:Milvus"
});
await client.ConnectAsync();
// Register the uploaded file under a name you'll reference from analyzer configs.
await client.AddFileResourceAsync(new AddFileResourceReq
{
Name = "zh_terms",
Path = "file/zh_terms.txt" // full S3 object key, including the rootPath prefix
});
# restful
curl --request POST \
--url "http://localhost:19530/v2/vectordb/file_resources/add" \
--header "Authorization: Bearer root:Milvus" \
--header "Content-Type: application/json" \
--data-raw '{
"name": "zh_terms",
"path": "file/zh_terms.txt"
}'
Verweisen Sie im Tokenizer über „ extra_dict_file “ auf die registrierte Ressource:
analyzer_params = {
"tokenizer": {
"type": "jieba",
"dict": ["_default_"], # keep the built-in dictionary
"mode": "exact",
"hmm": False,
"extra_dict_file": {
"type": "remote",
"resource_name": "zh_terms",
"file_name": "zh_terms.txt",
},
},
}
result = client.run_analyzer("milvus结巴分词器中文测试", analyzer_params)
print(result)
import io.milvus.v2.service.vector.request.RunAnalyzerReq;
import io.milvus.v2.service.vector.response.RunAnalyzerResp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", new HashMap<String, Object>() {{
put("type", "jieba");
put("dict", Collections.singletonList("_default_"));
put("mode", "exact");
put("hmm", false);
put("extra_dict_file", new HashMap<String, Object>() {{
put("type", "remote");
put("resource_name", "zh_terms");
put("file_name", "zh_terms.txt");
}});
}});
List<String> texts = new ArrayList<>();
texts.add("milvus结巴分词器中文测试");
RunAnalyzerResp resp = client.runAnalyzer(RunAnalyzerReq.builder()
.texts(texts)
.analyzerParams(analyzerParams)
.build());
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v3/milvusclient"
)
texts := []string{"milvus结巴分词器中文测试"}
option := milvusclient.NewRunAnalyzerOption(texts...).
WithAnalyzerParams(analyzerParams)
result, err := client.RunAnalyzer(ctx, option)
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, r := range result {
for _, token := range r.Tokens {
fmt.Println("Jieba analyzer output:", token.Text)
}
}
use milvus::v2::prelude::*;
let analyzer_params = serde_json::json!({
"tokenizer": {
"type": "jieba",
"dict": ["_default_"],
"mode": "exact",
"hmm": false,
"extra_dict_file": {
"type": "remote",
"resource_name": "zh_terms",
"file_name": "zh_terms.txt"
}
}
});
let response = client.run_analyzer(RunAnalyzerRequest::builder()
.texts(["milvus结巴分词器中文测试"])
.analyzer_params(analyzer_params)
.build()?).await?;
println!("{:?}", response.results());
#include <iostream>
#include "milvus/MilvusClientV2.h"
nlohmann::json analyzer_params = {
{"tokenizer", {
{"type", "jieba"},
{"dict", {"_default_"}},
{"mode", "exact"},
{"hmm", false},
{"extra_dict_file", {
{"type", "remote"},
{"resource_name", "zh_terms"},
{"file_name", "zh_terms.txt"}
}}
}}
};
milvus::RunAnalyzerRequest request;
request.WithAnalyzerParams(analyzer_params);
request.AddText("milvus结巴分词器中文测试");
milvus::RunAnalyzerResponse response;
status = client->RunAnalyzer(request, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
const analyzer_params = {
tokenizer: {
type: "jieba",
dict: ["_default_"],
mode: "exact",
hmm: false,
extra_dict_file: {
type: "remote",
resource_name: "zh_terms",
file_name: "zh_terms.txt",
},
},
};
const result = await client.runAnalyzer({
text: "milvus结巴分词器中文测试",
analyzer_params,
});
console.log(result.results);
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Utility;
using Milvus.Client.V2.Responses.Utility;
var analyzerParams = new Dictionary<string, object>
{
["tokenizer"] = new Dictionary<string, object>
{
["type"] = "jieba",
["dict"] = new[] { "_default_" }, // keep the built-in dictionary
["mode"] = "exact",
["hmm"] = false,
["extra_dict_file"] = new Dictionary<string, object>
{
["type"] = "remote",
["resource_name"] = "zh_terms",
["file_name"] = "zh_terms.txt"
}
}
};
var result = await client.RunAnalyzerAsync(new RunAnalyzerReq
{
AnalyzerParams = analyzerParams,
Texts = new[] { "milvus结巴分词器中文测试" }
});
curl --request POST \
--url "http://localhost:19530/v2/vectordb/common/run_analyzer" \
--header "Authorization: Bearer root:Milvus" \
--header "Content-Type: application/json" \
--data-raw '{
"text": ["milvus结巴分词器中文测试"],
"analyzerParams": "{\"tokenizer\":{\"type\":\"jieba\",\"dict\":[\"_default_\"],\"mode\":\"exact\",\"hmm\":false,\"extra_dict_file\":{\"type\":\"remote\",\"resource_name\":\"zh_terms\",\"file_name\":\"zh_terms.txt\"}}}"
}'
Der Parameter „ extra_dict_file “ akzeptiert ein Objekt mit den folgenden Feldern:
Feld |
Beschreibung |
|---|---|
|
Der Ressourcentyp. Verwenden Sie „ |
|
Der Name, der bei der Registrierung der Datei unter |
|
Der Dateinamensteil des Objekt-Speicherpfads der registrierten Ressource (z. B. |
Über extra_dict_file hinzugefügte Wörter werden mit dem integrierten Wörterbuch zusammengeführt, sodass der Segmentierungsalgorithmus von jieba sie zusammen mit bestehenden Einträgen berücksichtigt. Ob ein bestimmter Begriff als eigenständiges Token erscheint, hängt von der wahrscheinlichkeitsgewichteten DAG-Auswahl von jieba ab – ein langer benutzerdefinierter Begriff wie 向量数据库 kann dennoch in 向量 + 数据库 aufgeteilt werden, wenn diese kürzeren Einträge im integrierten Wörterbuch häufiger vorkommen.
Beispiele
Bevor Sie die Konfiguration des Analysators auf Ihr Sammlungsschema anwenden, überprüfen Sie dessen Verhalten mithilfe der Methode „ run_analyzer “.
Analysator-Konfiguration
analyzer_params = {
"tokenizer": {
"type": "jieba",
"dict": ["结巴分词器"],
"mode": "exact",
"hmm": False
}
}
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("tokenizer", new HashMap<String, Object>() {{
put("type", "jieba");
put("dict", Arrays.asList("结巴分词器"));
put("mode", "exact");
put("hmm", false);
}});
analyzerParams := map[string]any{
"tokenizer": map[string]any{
"type": "jieba",
"dict": []string{"结巴分词器"},
"mode": "exact",
"hmm": false,
},
}
use serde_json::json;
let analyzer_params = json!({
"tokenizer": {
"type": "jieba",
"dict": ["结巴分词器"],
"mode": "exact",
"hmm": false
}
});
nlohmann::json analyzer_params = {
{"tokenizer", {
{"type", "jieba"},
{"dict", {"结巴分词器"}},
{"mode", "exact"},
{"hmm", false}
}}
};
const analyzer_params = {
tokenizer: {
type: "jieba",
dict: ["结巴分词器"],
mode: "exact",
hmm: false,
},
};
var analyzerParams = new Dictionary<string, object>
{
["tokenizer"] = new Dictionary<string, object>
{
["type"] = "jieba",
["dict"] = new[] { "结巴分词器" },
["mode"] = "exact",
["hmm"] = false
}
};
# restful
analyzerParams='{
"tokenizer": {
"type": "jieba",
"dict": ["结巴分词器"],
"mode": "exact",
"hmm": false
}
}'
Überprüfung mit run_analyzer
from pymilvus import (
MilvusClient,
)
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
# Sample text to analyze
sample_text = "milvus结巴分词器中文测试"
# Run the jieba tokenizer with the defined configuration
result = client.run_analyzer(sample_text, analyzer_params)
print("Jieba analyzer output:", result)
import java.util.*;
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;
ConnectConfig config = ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build();
MilvusClientV2 client = new MilvusClientV2(config);
List<String> texts = new ArrayList<>();
texts.add("milvus结巴分词器中文测试");
RunAnalyzerResp resp = client.runAnalyzer(RunAnalyzerReq.builder()
.texts(texts)
.analyzerParams(analyzerParams)
.build());
List<RunAnalyzerResp.AnalyzerResult> results = resp.getResults();
for (RunAnalyzerResp.AnalyzerResult result : results) {
for (RunAnalyzerResp.AnalyzerToken token : result.getTokens()) {
System.out.println("Jieba analyzer output: " + token.getToken());
}
}
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v3/milvusclient"
)
ctx := context.Background()
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "http://localhost:19530",
APIKey: "root:Milvus",
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
texts := []string{"milvus结巴分词器中文测试"}
option := milvusclient.NewRunAnalyzerOption(texts...).
WithAnalyzerParams(analyzerParams)
result, err := client.RunAnalyzer(ctx, option)
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, r := range result {
for _, token := range r.Tokens {
fmt.Println("Jieba analyzer output:", token.Text)
}
}
use milvus::v2::prelude::*;
let config = ConnectConfig::new().uri("http://localhost:19530").token("root:Milvus");
let client = ClientV2::new(&config).await?;
let response = client
.run_analyzer(
RunAnalyzerRequest::builder()
.texts(["milvus结巴分词器中文测试"])
.analyzer_params(analyzer_params)
.build()?,
)
.await?;
for result in response.results() {
for token in result.get_tokens() {
println!("Jieba analyzer output: {}", token.get_text());
}
}
#include "milvus/MilvusClientV2.h"
#include <iostream>
#include <string>
auto client = milvus::MilvusClientV2::Create();
milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
std::string text = "milvus结巴分词器中文测试";
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;
}
for (const auto& result : response.Results()) {
for (const auto& token : result.Tokens()) {
std::cout << "Jieba analyzer output: " << token.token_ << std::endl;
}
}
import { MilvusClient } from '@zilliz/milvus2-sdk-node';
const client = new MilvusClient({
address: 'http://localhost:19530',
token: 'root:Milvus',
});
const sample_text = 'milvus结巴分词器中文测试';
const result = await client.runAnalyzer({
text: sample_text,
analyzer_params,
});
const tokens = result.results.flatMap(r => r.tokens.map(t => t.token));
console.log('Jieba analyzer output:', tokens);
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Utility;
using Milvus.Client.V2.Responses.Utility;
using Milvus.Client.V2.Types;
using var client = new MilvusClientV2(new ConnectConfig
{
Uri = "http://localhost:19530",
ApiKey = "root:Milvus"
});
await client.ConnectAsync();
// Sample text to analyze
var sampleText = "milvus结巴分词器中文测试";
// Run the jieba tokenizer with the defined configuration
RunAnalyzerResp result = await client.RunAnalyzerAsync(new RunAnalyzerReq
{
AnalyzerParams = analyzerParams,
Texts = new[] { sampleText }
});
foreach (AnalyzerResult r in result.Results)
{
foreach (AnalyzerToken t in r.Tokens)
{
Console.WriteLine($"Jieba analyzer output: {t.Token}");
}
}
curl --request POST \
--url "http://localhost:19530/v2/vectordb/common/run_analyzer" \
--header "Authorization: Bearer root:Milvus" \
--header "Content-Type: application/json" \
--data-raw '{
"text": ["milvus结巴分词器中文测试"],
"analyzerParams": "{\"tokenizer\":{\"type\":\"jieba\",\"dict\":[\"结巴分词器\"],\"mode\":\"exact\",\"hmm\":false}}"
}'
Erwartete Ausgabe
Für den Beispieltext erzeugt der Analysator die folgenden Token in der angegebenen Reihenfolge. Die SDK-Antwortobjekte und die Ausgabeformatierung variieren je nach Sprache; die REST-Antwort enthält diese Token unter data.results[].tokens[].token.
['milvus', '结巴分词器', '中', '文', '测', '试']