🚀 Попробуйте Zilliz Cloud, полностью управляемый Milvus, бесплатно — ощутите 10-кратное увеличение производительности! Попробовать сейчас>

milvus-logo
LFAI
Главная
  • Руководство пользователя
  • Home
  • Docs
  • Руководство пользователя

  • Поиск и ранжирование

  • Гибридный поиск

Гибридный поиск

Гибридный поиск - это метод поиска, при котором одновременно выполняется несколько ANN-поисков, перебираются несколько наборов результатов этих ANN-поисков и в итоге возвращается один набор результатов. Использование гибридного поиска позволяет повысить точность поиска. Zilliz поддерживает проведение гибридного поиска в коллекции с несколькими векторными полями.

Гибридный поиск чаще всего используется в сценариях, включающих поиск по разреженным и плотным векторам и мультимодальный поиск. В этом руководстве на конкретном примере показано, как проводить гибридный поиск в Zilliz.

Сценарии

Гибридный поиск подходит для следующих двух сценариев.

Различные типы векторов могут представлять различную информацию, а использование различных моделей встраивания позволяет более полно представить различные особенности и аспекты данных. Например, при использовании различных моделей встраивания для одного и того же предложения можно сгенерировать плотный вектор для представления семантического значения и разреженный вектор для представления частоты слов в предложении.

  • Разреженные векторы: Разреженные векторы характеризуются высокой размерностью вектора и наличием небольшого количества ненулевых значений. Такая структура делает их особенно хорошо подходящими для традиционных приложений информационного поиска. В большинстве случаев количество измерений, используемых в разреженных векторах, соответствует различным лексемам в одном или нескольких языках. Каждому измерению присваивается значение, которое указывает на относительную важность этой лексемы в документе. Такая схема удобна для задач, связанных с сопоставлением текстов.

  • Плотные векторы: Плотные векторы - это вкрапления, полученные из нейронных сетей. Будучи расположенными в упорядоченном массиве, эти векторы отражают семантическую сущность входного текста. Обратите внимание, что плотные векторы не ограничиваются обработкой текста; они также широко используются в компьютерном зрении для представления семантики визуальных данных. Эти плотные векторы, обычно генерируемые моделями встраивания текста, характеризуются тем, что большинство или все элементы являются ненулевыми. Таким образом, плотные векторы особенно эффективны для приложений семантического поиска, поскольку они могут возвращать наиболее похожие результаты на основе векторного расстояния даже при отсутствии точных текстовых совпадений. Эта возможность позволяет получить более тонкие и учитывающие контекст результаты поиска, часто улавливая взаимосвязи между понятиями, которые могут быть упущены при использовании подходов, основанных на ключевых словах.

Более подробную информацию см. в разделах "Разреженный вектор" и "Плотный вектор".

Мультимодальный поиск - это поиск сходства между неструктурированными данными в нескольких модальностях (например, изображения, видео, аудио, текст и т. д.). Например, человек может быть представлен с помощью различных модальностей данных, таких как отпечатки пальцев, отпечатки голоса и черты лица. Гибридный поиск поддерживает несколько поисков одновременно. Например, поиск человека по схожим отпечаткам пальцев и отпечаткам голоса.

Рабочий процесс

Основной рабочий процесс при проведении гибридного поиска выглядит следующим образом.

  1. Генерирование плотных векторов с помощью моделей встраивания, таких как BERT и Transformers.

  2. Генерирование разреженных векторов с помощью таких моделей встраивания, как BM25, BGE-M3, SPLADE и т. д.

  3. Создайте коллекцию в Zilliz и определите схему коллекции, включающую плотные и разреженные векторные поля.

  4. Вставьте разреженные векторы в коллекцию, только что созданную на предыдущем этапе.

  5. Проведите гибридный поиск: ANN-поиск по плотным векторам вернет набор топ-K наиболее похожих результатов, а текстовое соответствие по разреженным векторам также вернет набор топ-K результатов.

  6. Нормализация: Нормализуйте оценки двух наборов топ-K результатов, преобразовав их в диапазон между [0,1].

  7. Выберите подходящую стратегию ранжирования для объединения и ранжирования двух наборов результатов top-K и, в конечном счете, верните окончательный набор результатов top-K.

Hybrid Search Workflow Рабочий процесс гибридного поиска

Примеры

В этом разделе на конкретном примере показано, как проводить гибридный поиск на разреженных векторах для повышения точности текстового поиска.

Создание коллекции с несколькими векторными полями

Процесс создания коллекции состоит из трех частей: определение схемы коллекции, настройка параметров индекса и создание коллекции.

Определение схемы

В этом примере необходимо определить несколько векторных полей в схеме коллекции. В настоящее время каждая коллекция по умолчанию может включать до 4 векторных полей. Но вы также можете изменить значение параметра proxy.maxVectorFieldNum чтобы при необходимости включить в коллекцию до 10 векторных полей.

В следующем примере определена схема коллекции, где dense и sparse - это два векторных поля.

  • id: Это поле служит первичным ключом для хранения текстовых идентификаторов. Тип данных этого поля - INT64.

  • text: Это поле используется для хранения текстового содержимого. Тип данных этого поля - VARCHAR, максимальная длина - 1000 символов.

  • dense: Это поле используется для хранения плотных векторов текстов. Тип данных этого поля - FLOAT_VECTOR, размерность вектора - 768.

  • sparse: Это поле используется для хранения разреженных векторов текстов. Тип данных этого поля - SPARSE_FLOAT_VECTOR.

# Create a collection in customized setup mode
from pymilvus import (
    MilvusClient, DataType
)

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus"
)

# Create schema
schema = MilvusClient.create_schema(
    auto_id=False,
    enable_dynamic_field=True,
)
# Add fields to schema
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=1000)
schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR)
schema.add_field(field_name="dense", datatype=DataType.FLOAT_VECTOR, dim=5)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .token("root:Milvus")
        .build());

CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.addField(AddFieldReq.builder()
        .fieldName("id")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .autoID(false)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("text")
        .dataType(DataType.VarChar)
        .maxLength(1000)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("dense")
        .dataType(DataType.FloatVector)
        .dimension(768)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("sparse")
        .dataType(DataType.SparseFloatVector)
        .build());

// WIP

import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});

// Create a collection in customized setup mode
// Define fields
const fields = [
    {
        name: "id",
        data_type: DataType.Int64,
        is_primary_key: true,
        auto_id: false
    },
    {
        name: "text",
        data_type: DataType.VarChar,
        max_length: 1000
    },
    {
        name: "sparse",
        data_type: DataType.SPARSE_FLOAT_VECTOR
    },
    {
        name: "dense",
        data_type: DataType.FloatVector,
        dim: 768
    }
]

export schema='{
        "autoId": false,
        "enabledDynamicField": true,
        "fields": [
            {
                "fieldName": "id",
                "dataType": "Int64",
                "isPrimary": true
            },
            {
                "fieldName": "text",
                "dataType": "VarChar",
                "elementTypeParams": {
                    "max_length": 1000
                }
            },
            {
                "fieldName": "sparse",
                "dataType": "SparseFloatVector"
            },
            {
                "fieldName": "dense",
                "dataType": "FloatVector",
                "elementTypeParams": {
                    "dim": "768"
                }
            }
        ]
    }'

При поиске разреженных векторов можно упростить процесс генерации разреженных векторов вкраплений, используя возможности полнотекстового поиска. Более подробную информацию см. в разделе "Полнотекстовый поиск".

Создание индекса

После определения схемы коллекции необходимо настроить индексы векторов и метрики сходства. В этом примере для плотного векторного поля dense создается индекс IVF_FLAT, а для разреженного векторного поля sparse- индекс SPARSE_INVERTED_INDEX. Чтобы узнать о типах поддерживаемых индексов, см. раздел "Объяснение индексов".

from pymilvus import MilvusClient

# Prepare index parameters
index_params = client.prepare_index_params()

# Add indexes
index_params.add_index(
    field_name="dense",
    index_name="dense_index",
    index_type="IVF_FLAT",
    metric_type="IP",
    params={"nlist": 128},
)

index_params.add_index(
    field_name="sparse",
    index_name="sparse_index",
    index_type="SPARSE_INVERTED_INDEX",  # Index type for sparse vectors
    metric_type="IP",  # Currently, only IP (Inner Product) is supported for sparse vectors
    params={"inverted_index_algo": "DAAT_MAXSCORE"},  # The ratio of small vector values to be dropped during indexing
)

import io.milvus.v2.common.IndexParam;
import java.util.*;

Map<String, Object> denseParams = new HashMap<>();
denseParams.put("nlist", 128);
IndexParam indexParamForDenseField = IndexParam.builder()
        .fieldName("dense")
        .indexName("dense_index")
        .indexType(IndexParam.IndexType.IVF_FLAT)
        .metricType(IndexParam.MetricType.IP)
        .extraParams(denseParams)
        .build();

Map<String, Object> sparseParams = new HashMap<>();
sparseParams.put("inverted_index_algo": "DAAT_MAXSCORE");
IndexParam indexParamForSparseField = IndexParam.builder()
        .fieldName("sparse")
        .indexName("sparse_index")
        .indexType(IndexParam.IndexType.SPARSE_INVERTED_INDEX)
        .metricType(IndexParam.MetricType.IP)
        .extraParams(sparseParams)
        .build();

List<IndexParam> indexParams = new ArrayList<>();
indexParams.add(indexParamForDenseField);
indexParams.add(indexParamForSparseField);

const index_params = [{
    field_name: "dense",
    index_type: "IVF_FLAT",
    metric_type: "IP"
},{
    field_name: "sparse",
    index_type: "SPARSE_INVERTED_INDEX",
    metric_type: "IP"
}]

export indexParams='[
        {
            "fieldName": "dense",
            "metricType": "IP",
            "indexName": "dense_index",
            "indexType":"IVF_FLAT",
            "params":{"nlist":128}
        },
        {
            "fieldName": "sparse",
            "metricType": "IP",
            "indexName": "sparse_index",
            "indexType": "SPARSE_INVERTED_INDEX"
        }
    ]'

Создание коллекции

Создайте коллекцию с именем demo со схемой коллекции и индексами, настроенными в предыдущих двух шагах.

from pymilvus import MilvusClient

client.create_collection(
    collection_name="hybrid_search_collection",
    schema=schema,
    index_params=index_params
)

CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
        .collectionName("hybrid_search_collection")
        .collectionSchema(schema)
        .indexParams(indexParams)
        .build();
client.createCollection(createCollectionReq);

res = await client.createCollection({
    collection_name: "hybrid_search_collection",
    fields: fields,
    index_params: index_params,
})

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\": \"hybrid_search_collection\",
    \"schema\": $schema,
    \"indexParams\": $indexParams
}"

Вставка данных

Вставьте разреженно-плотные векторы в коллекцию demo.

from pymilvus import MilvusClient

data=[
    {"id": 0, "text": "Artificial intelligence was founded as an academic discipline in 1956.", "sparse":{9637: 0.30856525997853057, 4399: 0.19771651149001523, ...}, "dense": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, ...]},
    {"id": 1, "text": "Alan Turing was the first person to conduct substantial research in AI.", "sparse":{6959: 0.31025067641541815, 1729: 0.8265339135915016, ...}, "dense": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, ...]},
    {"id": 2, "text": "Born in Maida Vale, London, Turing was raised in southern England.", "sparse":{1220: 0.15303302147479103, 7335: 0.9436728846033107, ...}, "dense": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, ...]}

res = client.insert(
    collection_name="hybrid_search_collection",
    data=data
)


import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.service.vector.request.InsertReq;

Gson gson = new Gson();
JsonObject row1 = new JsonObject();
row1.addProperty("id", 1);
row1.addProperty("text", "Artificial intelligence was founded as an academic discipline in 1956.");
row1.add("dense", gson.toJsonTree(dense1));
row1.add("sparse", gson.toJsonTree(sparse1));

JsonObject row2 = new JsonObject();
row2.addProperty("id", 2);
row2.addProperty("text", "Alan Turing was the first person to conduct substantial research in AI.");
row2.add("dense", gson.toJsonTree(dense2));
row2.add("sparse", gson.toJsonTree(sparse2));

JsonObject row3 = new JsonObject();
row3.addProperty("id", 3);
row3.addProperty("text", "Born in Maida Vale, London, Turing was raised in southern England.");
row3.add("dense", gson.toJsonTree(dense3));
row3.add("sparse", gson.toJsonTree(sparse3));

List<JsonObject> data = Arrays.asList(row1, row2, row3);
InsertReq insertReq = InsertReq.builder()
        .collectionName("hybrid_search_collection")
        .data(data)
        .build();

InsertResp insertResp = client.insert(insertReq);

const { MilvusClient, DataType } = require("@zilliz/milvus2-sdk-node")

var data = [
    {id: 0, text: "Artificial intelligence was founded as an academic discipline in 1956.", sparse:[9637: 0.30856525997853057, 4399: 0.19771651149001523, ...] , dense: [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]},
    {id: 1, text: "Alan Turing was the first person to conduct substantial research in AI.", sparse:[6959: 0.31025067641541815, 1729: 0.8265339135915016, ...] , dense: [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]},
    {id: 2, text: "Born in Maida Vale, London, Turing was raised in southern England." , sparse:[1220: 0.15303302147479103, 7335: 0.9436728846033107, ...] , dense: [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, 0.7894058910881185, 0.20785793220625592]}       
]

var res = await client.insert({
    collection_name: "hybrid_search_collection",
    data: data,
})

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "data": [
        {"id": 0, "text": "Artificial intelligence was founded as an academic discipline in 1956.", "sparse":{"9637": 0.30856525997853057, "4399": 0.19771651149001523}, "dense": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, ...]},
        {"id": 1, "text": "Alan Turing was the first person to conduct substantial research in AI.", "sparse":{"6959": 0.31025067641541815, "1729": 0.8265339135915016}, "dense": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, ...]},
        {"id": 2, "text": "Born in Maida Vale, London, Turing was raised in southern England.", "sparse":{"1220": 0.15303302147479103, "7335": 0.9436728846033107}, "dense": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, ...]}
    ],
    "collectionName": "hybrid_search_collection"
}'

Создание нескольких экземпляров AnnSearchRequest

Гибридный поиск реализуется путем создания нескольких AnnSearchRequest в функции hybrid_search(), где каждый AnnSearchRequest представляет собой базовый запрос на поиск ANN для определенного векторного поля. Поэтому перед проведением гибридного поиска необходимо создать AnnSearchRequest для каждого векторного поля.

В гибридном поиске каждый AnnSearchRequest поддерживает только один вектор запроса.

Предположим, текст запроса "Кто начал исследования ИИ?" уже преобразован в разреженный и плотный векторы. Исходя из этого, создаются два поисковых запроса AnnSearchRequest для векторных полей sparse и dense соответственно, как показано в следующем примере.

from pymilvus import AnnSearchRequest

query_dense_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

search_param_1 = {
    "data": [query_dense_vector],
    "anns_field": "dense",
    "param": {
        "metric_type": "IP",
        "params": {"nprobe": 10}
    },
    "limit": 2
}
request_1 = AnnSearchRequest(**search_param_1)

query_sparse_vector = {3573: 0.34701499565746674}, {5263: 0.2639375518635271}
search_param_2 = {
    "data": [query_sparse_vector],
    "anns_field": "sparse",
    "param": {
        "metric_type": "IP",
        "params": {}
    },
    "limit": 2
}
request_2 = AnnSearchRequest(**search_param_2)

reqs = [request_1, request_2]


import io.milvus.v2.service.vector.request.AnnSearchReq;
import io.milvus.v2.service.vector.request.data.BaseVector;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.request.data.SparseFloatVec;

float[] dense = new float[]{-0.0475336798f,  0.0521207601f,  0.0904406682f, ...};
SortedMap<Long, Float> sparse = new TreeMap<Long, Float>() {{
    put(3573L, 0.34701499f);
    put(5263L, 0.263937551f);
    ...
}};


List<BaseVector> queryDenseVectors = Collections.singletonList(new FloatVec(dense));
List<BaseVector> querySparseVectors = Collections.singletonList(new SparseFloatVec(sparse));

List<AnnSearchReq> searchRequests = new ArrayList<>();
searchRequests.add(AnnSearchReq.builder()
        .vectorFieldName("dense")
        .vectors(queryDenseVectors)
        .metricType(IndexParam.MetricType.IP)
        .params("{\"nprobe\": 10}")
        .topK(2)
        .build());
searchRequests.add(AnnSearchReq.builder()
        .vectorFieldName("sparse")
        .vectors(querySparseVectors)
        .metricType(IndexParam.MetricType.IP)
        .params()
        .topK(2)
        .build());

const search_param_1 = {
    "data": query_vector, 
    "anns_field": "dense", 
    "param": {
        "metric_type": "IP", 
        "params": {"nprobe": 10}
    },
    "limit": 2 
}

const search_param_2 = {
    "data": query_sparse_vector, 
    "anns_field": "sparse", 
    "param": {
        "metric_type": "IP", 
        "params": {}
    },
    "limit": 2 
}

export req='[
    {
        "data": [[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592,....]],
        "annsField": "dense",
        "params": {
            "params": {
                "nprobe": 10
             }
        },
        "limit": 2
    },
    {
        "data": [{"3573": 0.34701499565746674}, {"5263": 0.2639375518635271}],
        "annsField": "sparse",
        "params": {
            "params": {}
        },
        "limit": 2
    }
 ]'

Поскольку параметр limit имеет значение 2, каждый AnnSearchRequest возвращает 2 результата поиска. В данном примере создано 2 AnnSearchRequest, поэтому всего будет возвращено 4 результата поиска.

Настройка стратегии ранжирования

Чтобы объединить и ранжировать два набора результатов поиска ANN, необходимо выбрать подходящую стратегию ранжирования. Zilliz поддерживает два типа стратегий ранжирования: WeightedRanker и RRFRanker. При выборе стратегии ранжирования следует учитывать, есть ли акцент на одном или нескольких базовых ANN-поисках по векторным полям.

  • WeightedRanker: Эта стратегия рекомендуется, если вы хотите, чтобы в результатах был сделан акцент на определенном векторном поле. WeightedRanker позволяет присваивать более высокие веса определенным векторным полям, делая на них больший акцент. Например, при мультимодальном поиске текстовые описания изображения могут считаться более важными, чем цвета на этом изображении.

  • RRFRanker (Reciprocal Rank Fusion Ranker): Эта стратегия рекомендуется, когда нет конкретного акцента. RRF может эффективно сбалансировать важность каждого векторного поля.

Более подробную информацию о механизмах работы этих двух стратегий ранжирования см. в разделе Ранжирование.

В следующих двух примерах показано, как использовать стратегии ранжирования WeightedRanker и RRFRanker.

  1. Пример 1: Использование WeightedRanker

    При использовании стратегии WeightedRanker необходимо ввести значения веса в функцию WeightedRanker. Количество базовых ANN в гибридном поиске соответствует количеству значений, которые необходимо ввести. Вводимые значения должны находиться в диапазоне [0,1], причем значения ближе к 1 означают большую важность.

    from pymilvus import WeightedRanker
    
    rerank= WeightedRanker(0.8, 0.3) 
    
    
    import io.milvus.v2.service.vector.request.ranker.BaseRanker;
    import io.milvus.v2.service.vector.request.ranker.WeightedRanker;
    
    BaseRanker reranker = new WeightedRanker(Arrays.asList(0.8f, 0.3f));
    
    
    import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
    
    const rerank = WeightedRanker(0.8, 0.3);
    
    
    export rerank='{
            "strategy": "ws",
            "params": {"weights": [0.8,0.3]}
        }'
    
    
  2. Пример 2: Использование RRFRanker

    При использовании стратегии RRFRanker необходимо ввести в RRFRanker значение параметра k. По умолчанию значение k равно 60. Этот параметр помогает определить, как объединяются ранги из разных поисковых запросов ANN, стремясь сбалансировать и объединить значимость всех поисковых запросов.

    from pymilvus import RRFRanker
    
    ranker = RRFRanker(100)
    
    
    import io.milvus.v2.service.vector.request.ranker.BaseRanker;
    import io.milvus.v2.service.vector.request.ranker.RRFRanker;
    
    BaseRanker reranker = new RRFRanker(100);
    
    
    import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
    
    const rerank = RRFRanker("100");
    
    
    export rerank='{
            "strategy": "rrf",
            "params": { "k": 100}
        }'
    
    

Перед проведением гибридного поиска необходимо загрузить коллекцию в память. Если какие-либо векторные поля коллекции не имеют индекса или не загружены, при вызове метода Hybrid Search возникнет ошибка.

from pymilvus import MilvusClient

res = client.hybrid_search(
    collection_name="hybrid_search_collection",
    reqs=reqs,
    ranker=ranker,
    limit=2
)
for hits in res:
    print("TopK results:")
    for hit in hits:
        print(hit)

import io.milvus.v2.common.ConsistencyLevel;
import io.milvus.v2.service.vector.request.HybridSearchReq;
import io.milvus.v2.service.vector.response.SearchResp;

HybridSearchReq hybridSearchReq = HybridSearchReq.builder()
        .collectionName("hybrid_search_collection")
        .searchRequests(searchRequests)
        .ranker(reranker)
        .topK(2)
        .consistencyLevel(ConsistencyLevel.BOUNDED)
        .build();

SearchResp searchResp = client.hybridSearch(hybridSearchReq);

const { MilvusClient, DataType } = require("@zilliz/milvus2-sdk-node")

res = await client.loadCollection({
    collection_name: "hybrid_search_collection"
})

import { MilvusClient, RRFRanker, WeightedRanker } from '@zilliz/milvus2-sdk-node';

const search = await client.search({
  collection_name: "hybrid_search_collection",
  data: [search_param_1, search_param_2],
  limit: 2,
  rerank: RRFRanker(100)
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/advanced_search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"hybrid_search_collection\",
    \"search\": ${req},
    \"rerank\": {
        \"strategy\":\"rrf\",
        \"params\": {
            \"k\": 10
        }
    },
    \"limit\": 3,
    \"outputFields\": [
        \"user_id\",
        \"word_count\",
        \"book_describe\"
    ]
}"

Ниже приведен результат.

["['id: 844, distance: 0.006047376897186041, entity: {}', 'id: 876, distance: 0.006422005593776703, entity: {}']"]

Поскольку в методе Hybrid Search указано limit=2, Zilliz проранжирует четыре результата поиска из шага 3 и в итоге вернет только 2 наиболее похожих результата поиска.

Попробуйте Managed Milvus бесплатно

Zilliz Cloud работает без проблем, поддерживается Milvus и в 10 раз быстрее.

Начать
Обратная связь

Была ли эта страница полезной?