🚀 免費嘗試 Zilliz Cloud,完全托管的 Milvus,體驗速度提升 10 倍!立即嘗試

milvus-logo
LFAI
主頁
  • 使用者指南
  • Home
  • Docs
  • 使用者指南

  • 搜尋與重新排名

  • 全文檢索

全文檢索

全文檢索是一種在文字資料集中擷取包含特定詞彙或短語的文件,然後根據相關性對結果進行排序的功能。此功能克服了語意搜尋可能會忽略精確詞彙的限制,確保您收到最精確且與上下文相關的結果。此外,它還可以接受原始文字輸入,自動將您的文字資料轉換為稀疏嵌入,而不需要手動產生向量嵌入,從而簡化向量搜尋。

使用 BM25 演算法進行相關性評分,此功能在檢索擴充生成 (RAG) 的情境中特別有價值,它會優先處理與特定搜尋詞彙密切相符的文件。

  • 透過整合全文檢索與以語意為基礎的密集向量檢索,您可以提高檢索結果的準確性與相關性。如需詳細資訊,請參閱混合搜尋
  • 全文搜索在 Milvus Standalone 和 Milvus Distributed 中可用,但在 Milvus Lite 中不可用,儘管將其加入 Milvus Lite 在路線圖上。

概述

全文檢索簡化了以文字為基礎的檢索過程,省去了手動嵌入的需要。此功能透過下列工作流程運作。

  1. 文字輸入:您可插入原始文字文件或提供查詢文字,而無需手動嵌入。

  2. 文字分析:關於分析器的更多資訊,請參閱分析器概述

  3. 函式處理:內建函式接收標記化的詞彙,並將它們轉換成稀疏向量表示。

  4. 集合儲存:Milvus 將這些稀疏嵌入資料儲存在一個集合中,以便進行有效的檢索。

  5. BM25 評分:在搜尋過程中,Milvus 應用 BM25 演算法來計算儲存文件的分數,並根據其與查詢文字的相關性對匹配結果進行排序。

Full text search 全文檢索

要使用全文本搜尋,請遵循以下主要步驟。

  1. 建立一個集合:設定一個包含必要欄位的集合,並定義一個函數將原始文字轉換為稀疏嵌入。

  2. 插入資料:將原始文字文件輸入到資料集中。

  3. 執行搜尋:使用查詢文字在您的資料集中搜尋,並擷取相關結果。

若要啟用全文本搜尋,請建立具有特定模式的資料夾。此模式必須包含三個必要欄位。

  • 唯一識別資料集中每一個實體的主要欄位。

  • 儲存原始文字文件的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": {}
            }
        ]
    }'

參數

說明

name

函式名稱。這個函式會將text 欄位中的原始文字轉換成可搜尋的向量,並儲存在sparse 欄位中。

input_field_names

需要將文字轉換為稀疏向量的VARCHAR 欄位名稱。對於FunctionType.BM25 ,此參數只接受一個欄位名稱。

output_field_names

儲存內部產生的稀疏向量的欄位名稱。對於FunctionType.BM25 ,此參數只接受一個欄位名稱。

function_type

要使用的函數類型。設定值為FunctionType.BM25

對於具有多個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"
        }
    ]'

參數

說明

field_name

要索引的向量欄位名稱。對於全文檢索,這應該是儲存所產生的稀疏向量的欄位。在本範例中,設定值為sparse

index_type

要建立的索引類型。AUTOINDEX 允許 Milvus 自動最佳化索引設定。如果您需要對索引設定有更多控制,您可以從 Milvus 中各種可用於稀疏向量的索引類型中選擇。如需更多資訊,請參考Milvus 支援的索引

metric_type

此參數的值必須設定為BM25 ,特別是針對全文檢索功能。

建立資料庫

現在使用已定義的模式和索引參數建立集合。

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
        }
    }
}'

參數

說明

search_params

包含搜尋參數的字典。

params.drop_ratio_search

搜尋時要忽略的低頻詞比例。如需詳細資訊,請參閱Sparse Vector

data

原始查詢文字。

anns_field

包含內部產生的稀疏向量的欄位名稱。

limit

要返回的最大頂端匹配數目。

免費嘗試托管的 Milvus

Zilliz Cloud 無縫接入,由 Milvus 提供動力,速度提升 10 倍。

開始使用
反饋

這個頁面有幫助嗎?