全文檢索
全文檢索是一種在文字資料集中擷取包含特定詞彙或短語的文件,然後根據相關性對結果進行排序的功能。此功能克服了語意搜尋可能會忽略精確詞彙的限制,確保您收到最精確且與上下文相關的結果。此外,它還可以接受原始文字輸入,自動將您的文字資料轉換為稀疏嵌入,而不需要手動產生向量嵌入,從而簡化向量搜尋。
使用 BM25 演算法進行相關性評分,此功能在檢索擴充生成 (RAG) 的情境中特別有價值,它會優先處理與特定搜尋詞彙密切相符的文件。
- 透過整合全文檢索與以語意為基礎的密集向量檢索,您可以提高檢索結果的準確性與相關性。如需詳細資訊,請參閱混合搜尋。
- 全文搜索在 Milvus Standalone 和 Milvus Distributed 中可用,但在 Milvus Lite 中不可用,儘管將其加入 Milvus Lite 在路線圖上。
概述
全文檢索簡化了以文字為基礎的檢索過程,省去了手動嵌入的需要。此功能透過下列工作流程運作。
文字輸入:您可插入原始文字文件或提供查詢文字,而無需手動嵌入。
文字分析:關於分析器的更多資訊,請參閱分析器概述。
函式處理:內建函式接收標記化的詞彙,並將它們轉換成稀疏向量表示。
集合儲存:Milvus 將這些稀疏嵌入資料儲存在一個集合中,以便進行有效的檢索。
BM25 評分:在搜尋過程中,Milvus 應用 BM25 演算法來計算儲存文件的分數,並根據其與查詢文字的相關性對匹配結果進行排序。
全文檢索
要使用全文本搜尋,請遵循以下主要步驟。
為全文本搜尋建立資料夾
若要啟用全文本搜尋,請建立具有特定模式的資料夾。此模式必須包含三個必要欄位。
唯一識別資料集中每一個實體的主要欄位。
儲存原始文字文件的
VARCHAR
欄位,其enable_analyzer
屬性設定為True
。這可讓 Milvus 將文字標記化為特定詞彙,以便進行功能處理。預留一個
SPARSE_FLOAT_VECTOR
欄位,用來儲存 Milvus 會自動為VARCHAR
欄位產生的稀疏嵌入。
定義集合模式
首先,建立模式並新增必要的欄位。
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"
}
]
}'
在此設定中。
id
: 用作主索引鍵,並由auto_id=True
自動產生。text
: 儲存您的原始文字資料,用於全文檢索作業。資料類型必須是VARCHAR
,因為VARCHAR
是 Milvus 用來儲存文字的字串資料類型。設定enable_analyzer=True
以允許 Milvus 對文字進行 tokenize。預設情況下,Milvus 使用標準分析器進行文字分析。要設定不同的分析器,請參考概述。sparse
資料類型:預留向量欄位,以儲存內部產生的稀疏嵌入,用於全文檢索作業。資料類型必須是SPARSE_FLOAT_VECTOR
。
現在,定義一個函式,將您的文字轉換為稀疏向量表示,然後將其加入模式。
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": {}
}
]
}'
參數 | 說明 |
---|---|
| 函式名稱。這個函式會將 |
| 需要將文字轉換為稀疏向量的 |
| 儲存內部產生的稀疏向量的欄位名稱。對於 |
| 要使用的函數類型。設定值為 |
對於具有多個VARCHAR
欄位、需要將文字轉換為稀疏向量的資料集,請在資料集模式中加入不同的函式,確保每個函式都有唯一的名稱和output_field_names
值。
設定索引
在定義包含必要欄位和內建函式的模式後,為您的集合設定索引。為了簡化這個過程,請使用AUTOINDEX
作為index_type
,這個選項允許 Milvus 根據您的資料結構選擇和設定最適合的索引類型。
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"
}
]'
參數 | 說明 |
---|---|
| 要索引的向量欄位名稱。對於全文檢索,這應該是儲存所產生的稀疏向量的欄位。在本範例中,設定值為 |
| 要建立的索引類型。 |
| 此參數的值必須設定為 |
建立資料庫
現在使用已定義的模式和索引參數建立集合。
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
}"
插入文字資料
設定好集合和索引後,您就可以插入文字資料了。在這個過程中,您只需要提供原始文字。我們之前定義的內建函式會自動為每個文字項目產生相對應的稀疏向量。
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"
}'
執行全文檢索
將資料插入資料庫後,您就可以使用原始文字查詢來執行全文檢索。Milvus 會自動將您的查詢轉換成稀疏向量,並使用 BM25 演算法對匹配的搜尋結果進行排序,然後傳回 topK (limit
) 結果。
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
}
}
}'
參數 | 說明 |
---|---|
| 包含搜尋參數的字典。 |
| 搜尋時要忽略的低頻詞比例。如需詳細資訊,請參閱Sparse Vector。 |
| 原始查詢文字。 |
| 包含內部產生的稀疏向量的欄位名稱。 |
| 要返回的最大頂端匹配數目。 |