Volltextsuche
Die Volltextsuche ist eine Funktion, die Dokumente mit bestimmten Begriffen oder Phrasen in Textdatensätzen abruft und die Ergebnisse dann nach Relevanz einstuft. Diese Funktion überwindet die Beschränkungen der semantischen Suche, bei der präzise Begriffe übersehen werden können, und stellt sicher, dass Sie die genauesten und kontextuell relevanten Ergebnisse erhalten. Darüber hinaus vereinfacht es die Vektorsuche, indem es Rohtexteingaben akzeptiert und Ihre Textdaten automatisch in spärliche Einbettungen konvertiert, ohne dass Sie manuell Vektoreinbettungen erstellen müssen.
Durch die Verwendung des BM25-Algorithmus für die Relevanzbewertung ist diese Funktion besonders wertvoll in Retrieval-Augmented-Generating-Szenarien (RAG), bei denen Dokumente mit hoher Übereinstimmung mit bestimmten Suchbegriffen priorisiert werden.
Durch die Integration der Volltextsuche mit der semantikbasierten dichten Vektorsuche können Sie die Genauigkeit und Relevanz der Suchergebnisse verbessern. Weitere Informationen finden Sie unter Hybride Suche.
Die Volltextsuche ist in Milvus Standalone und Milvus Distributed verfügbar, aber nicht in Milvus Lite, obwohl die Aufnahme in Milvus Lite auf der Roadmap steht.
Überblick
Die Volltextsuche vereinfacht den Prozess der textbasierten Suche, indem sie die Notwendigkeit der manuellen Einbettung eliminiert. Diese Funktion funktioniert über den folgenden Arbeitsablauf.
Texteingabe: Sie fügen Rohtextdokumente ein oder stellen Abfragetext bereit, ohne dass eine manuelle Einbettung erforderlich ist.
Text-Analyse: Milvus verwendet einen Analyzer, der den eingegebenen Text in einzelne, durchsuchbare Begriffe zerlegt. Weitere Informationen zu Analyzern finden Sie unter Analyzer-Übersicht.
Funktionsverarbeitung: Die integrierte Funktion empfängt tokenisierte Begriffe und konvertiert sie in spärliche Vektordarstellungen.
Sammlungsspeicher: Milvus speichert diese spärlichen Einbettungen in einer Sammlung, um sie effizient abrufen zu können.
BM25-Bewertung: Während einer Suche wendet Milvus den BM25-Algorithmus an, um die Punktzahlen für die gespeicherten Dokumente zu berechnen und die übereinstimmenden Ergebnisse nach ihrer Relevanz für den Abfragetext zu ordnen.
Volltextsuche
Um die Volltextsuche zu nutzen, führen Sie die folgenden Schritte aus.
Erstellen Sie eine Sammlung: Richten Sie eine Sammlung mit den erforderlichen Feldern ein und definieren Sie eine Funktion zur Umwandlung von Rohtext in Sparse Embeddings.
Daten einfügen: Fügen Sie Ihre Rohtextdokumente in die Sammlung ein.
Suchen durchführen: Verwenden Sie Abfragetexte, um Ihre Sammlung zu durchsuchen und relevante Ergebnisse zu erhalten.
Erstellen Sie eine Sammlung für die Volltextsuche
Um die Volltextsuche zu ermöglichen, erstellen Sie eine Sammlung mit einem bestimmten Schema. Dieses Schema muss drei notwendige Felder enthalten.
Das Primärfeld, das jede Entität in einer Sammlung eindeutig identifiziert.
Ein
VARCHAR
-Feld, das Rohtextdokumente speichert, wobei dasenable_analyzer
-Attribut aufTrue
gesetzt ist. Dies ermöglicht Milvus die Tokenisierung von Text in spezifische Begriffe für die Funktionsverarbeitung.Ein
SPARSE_FLOAT_VECTOR
Feld, das für die Speicherung von Sparse Embeddings reserviert ist, die Milvus automatisch für dasVARCHAR
Feld generiert.
Definieren Sie das Sammlungsschema
Erstellen Sie zunächst das Schema und fügen Sie die erforderlichen Felder hinzu.
from pymilvus import MilvusClient, DataType, Function, FunctionType
client = MilvusClient(uri="http://localhost:19530")
schema = client.create_schema()
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True)
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=1000, enable_analyzer=True)
schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR)
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder()
.build();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.autoID(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("text")
.dataType(DataType.VarChar)
.maxLength(1000)
.enableAnalyzer(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("sparse")
.dataType(DataType.SparseFloatVector)
.build());
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});
const schema = [
{
name: "id",
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: "text",
data_type: "VarChar",
enable_analyzer: true,
enable_match: true,
max_length: 1000,
},
{
name: "sparse",
data_type: DataType.SparseFloatVector,
},
];
console.log(res.results)
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 1000,
"enable_analyzer": true
}
},
{
"fieldName": "sparse",
"dataType": "SparseFloatVector"
}
]
}'
In dieser Konfiguration.
id
: dient als Primärschlüssel und wird automatisch mitauto_id=True
generiert.text
: speichert Ihre Rohtextdaten für Volltextsuchvorgänge. Der Datentyp mussVARCHAR
sein, daVARCHAR
der String-Datentyp von Milvus für die Textspeicherung ist. Setzen Sieenable_analyzer=True
, um Milvus die Tokenisierung des Textes zu ermöglichen. Standardmäßig verwendet Milvus den Standard-Analysator für die Textanalyse. Um einen anderen Analyzer zu konfigurieren, siehe Übersicht.sparse
: ein Vektorfeld, das für die Speicherung von intern generierten Sparse Embeddings für Volltextsuchoperationen reserviert ist. Der Datentyp mussSPARSE_FLOAT_VECTOR
sein.
Definieren Sie nun eine Funktion, die Ihren Text in Sparse-Vektor-Darstellungen umwandelt, und fügen Sie sie dann dem Schema hinzu.
bm25_function = Function(
name="text_bm25_emb", # Function name
input_field_names=["text"], # Name of the VARCHAR field containing raw text data
output_field_names=["sparse"], # Name of the SPARSE_FLOAT_VECTOR field reserved to store generated embeddings
function_type=FunctionType.BM25,
)
schema.add_function(bm25_function)
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq.Function;
import java.util.*;
schema.addFunction(Function.builder()
.functionType(FunctionType.BM25)
.name("text_bm25_emb")
.inputFieldNames(Collections.singletonList("text"))
.outputFieldNames(Collections.singletonList("vector"))
.build());
const functions = [
{
name: 'text_bm25_emb',
description: 'bm25 function',
type: FunctionType.BM25,
input_field_names: ['text'],
output_field_names: ['vector'],
params: {},
},
];
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 1000,
"enable_analyzer": true
}
},
{
"fieldName": "sparse",
"dataType": "SparseFloatVector"
}
],
"functions": [
{
"name": "text_bm25_emb",
"type": "BM25",
"inputFieldNames": ["text"],
"outputFieldNames": ["sparse"],
"params": {}
}
]
}'
Parameter | Beschreibung |
---|---|
| Der Name der Funktion. Diese Funktion wandelt Ihren Rohtext aus dem Feld |
| Der Name des Feldes |
| Der Name des Feldes, in dem die intern erzeugten Sparse-Vektoren gespeichert werden. Für |
| Der Typ der zu verwendenden Funktion. Setzen Sie den Wert auf |
Für Sammlungen mit mehreren VARCHAR
Feldern, die eine Konvertierung von Text in Sparse Vectors erfordern, fügen Sie separate Funktionen zum Sammlungsschema hinzu und stellen sicher, dass jede Funktion einen eindeutigen Namen und output_field_names
Wert hat.
Konfigurieren Sie den Index
Nachdem Sie das Schema mit den erforderlichen Feldern und der integrierten Funktion definiert haben, richten Sie den Index für Ihre Sammlung ein. Um diesen Prozess zu vereinfachen, verwenden Sie AUTOINDEX
als index_type
, eine Option, die es Milvus ermöglicht, den am besten geeigneten Indextyp basierend auf der Struktur Ihrer Daten auszuwählen und zu konfigurieren.
index_params = client.prepare_index_params()
index_params.add_index(
field_name="sparse",
index_type="AUTOINDEX",
metric_type="BM25"
)
import io.milvus.v2.common.IndexParam;
List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
.fieldName("sparse")
.indexType(IndexParam.IndexType.SPARSE_INVERTED_INDEX)
.metricType(IndexParam.MetricType.BM25)
.build());
const index_params = [
{
field_name: "sparse",
metric_type: "BM25",
index_type: "AUTOINDEX",
},
];
export indexParams='[
{
"fieldName": "sparse",
"metricType": "BM25",
"indexType": "AUTOINDEX"
}
]'
Parameter | Beschreibung |
---|---|
| Der Name des zu indizierenden Vektorfeldes. Für die Volltextsuche sollte dies das Feld sein, das die generierten Sparse-Vektoren speichert. In diesem Beispiel setzen Sie den Wert auf |
| Der Typ des zu erstellenden Indexes. |
| Der Wert für diesen Parameter muss speziell für die Volltextsuchfunktionalität auf |
Erstellen Sie die Sammlung
Erstellen Sie nun die Sammlung unter Verwendung der definierten Schema- und Indexparameter.
client.create_collection(
collection_name='demo',
schema=schema,
index_params=index_params
)
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("demo")
.collectionSchema(schema)
.indexParams(indexes)
.build();
client.createCollection(requestCreate);
await client.create_collection(
collection_name: 'demo',
schema: schema,
index_params: index_params,
functions: functions
);
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
\"collectionName\": \"demo\",
\"schema\": $schema,
\"indexParams\": $indexParams
}"
Textdaten einfügen
Nachdem Sie Ihre Sammlung und Ihren Index eingerichtet haben, können Sie nun Textdaten einfügen. Bei diesem Vorgang müssen Sie nur den Rohtext bereitstellen. Die integrierte Funktion, die wir zuvor definiert haben, erzeugt automatisch den entsprechenden Sparse-Vektor für jeden Texteintrag.
client.insert('demo', [
{'text': 'information retrieval is a field of study.'},
{'text': 'information retrieval focuses on finding relevant information in large datasets.'},
{'text': 'data mining and information retrieval overlap in research.'},
])
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.service.vector.request.InsertReq;
Gson gson = new Gson();
List<JsonObject> rows = Arrays.asList(
gson.fromJson("{\"text\": \"information retrieval is a field of study.\"}", JsonObject.class),
gson.fromJson("{\"text\": \"information retrieval focuses on finding relevant information in large datasets.\"}", JsonObject.class),
gson.fromJson("{\"text\": \"data mining and information retrieval overlap in research.\"}", JsonObject.class)
);
client.insert(InsertReq.builder()
.collectionName("demo")
.data(rows)
.build());
await client.insert({
collection_name: 'demo',
data: [
{'text': 'information retrieval is a field of study.'},
{'text': 'information retrieval focuses on finding relevant information in large datasets.'},
{'text': 'data mining and information retrieval overlap in research.'},
]);
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"data": [
{"text": "information retrieval is a field of study."},
{"text": "information retrieval focuses on finding relevant information in large datasets."},
{"text": "data mining and information retrieval overlap in research."}
],
"collectionName": "demo"
}'
Volltextsuche durchführen
Sobald Sie Daten in Ihre Sammlung eingefügt haben, können Sie eine Volltextsuche mit Rohtextabfragen durchführen. Milvus konvertiert Ihre Abfrage automatisch in einen Sparse-Vektor und ordnet die übereinstimmenden Suchergebnisse mit dem BM25-Algorithmus ein und gibt dann die TopK (limit
) Ergebnisse zurück.
search_params = {
'params': {'drop_ratio_search': 0.2},
}
client.search(
collection_name='demo',
data=['whats the focus of information retrieval?'],
anns_field='sparse',
limit=3,
search_params=search_params
)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
Map<String,Object> searchParams = new HashMap<>();
searchParams.put("drop_ratio_search", 0.2);
SearchResp searchResp = client.search(SearchReq.builder()
.collectionName("demo")
.data(Collections.singletonList(new EmbeddedText("whats the focus of information retrieval?")))
.annsField("sparse")
.topK(3)
.searchParams(searchParams)
.outputFields(Collections.singletonList("text"))
.build());
await client.search(
collection_name: 'demo',
data: ['whats the focus of information retrieval?'],
anns_field: 'sparse',
limit: 3,
params: {'drop_ratio_search': 0.2},
)
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data-raw '{
"collectionName": "demo",
"data": [
"whats the focus of information retrieval?"
],
"annsField": "sparse",
"limit": 3,
"outputFields": [
"text"
],
"searchParams":{
"params":{
"drop_ratio_search":0.2
}
}
}'
Parameter | Beschreibung |
---|---|
| Ein Wörterbuch mit Suchparametern. |
| Anteil der niederfrequenten Begriffe, die bei der Suche ignoriert werden sollen. Einzelheiten finden Sie unter Sparse Vector. |
| Der rohe Abfragetext. |
| Der Name des Feldes, das intern generierte Sparse-Vektoren enthält. |
| Maximale Anzahl der zurückzugebenden Top-Treffer. |