البحث الهجين
يشير البحث المختلط إلى طريقة بحث تُجري عمليات بحث متعددة للشبكات العصبية الاصطناعية في وقت واحد، وتعيد ترتيب مجموعات متعددة من النتائج من عمليات البحث هذه، ثم تُرجع في النهاية مجموعة واحدة من النتائج. يمكن أن يؤدي استخدام البحث الهجين إلى تحسين دقة البحث. يدعم Zilliz إجراء بحث هجين على مجموعة ذات حقول متجهة متعددة.
يُستخدم البحث الهجين بشكل شائع في سيناريوهات تشمل عمليات البحث عن المتجهات المتفرقة الكثيفة وعمليات البحث متعددة الوسائط. سيوضح هذا الدليل كيفية إجراء بحث هجين في Zilliz مع مثال محدد.
السيناريوهات
البحث الهجين مناسب للسيناريوهين التاليين.
بحث متناثر - كثيف المتجهات
يمكن لأنواع مختلفة من المتجهات أن تمثل معلومات مختلفة، ويمكن أن يؤدي استخدام نماذج تضمين مختلفة إلى تمثيل ميزات وجوانب مختلفة من البيانات بشكل أكثر شمولاً. على سبيل المثال، يمكن أن يؤدي استخدام نماذج تضمين مختلفة لنفس الجملة إلى توليد متجه كثيف لتمثيل المعنى الدلالي ومتجه متناثر لتمثيل تكرار الكلمات في الجملة.
المتجهات المتفرقة: تتميز المتجهات المتفرقة بأبعادها المتجهة العالية ووجود عدد قليل من القيم غير الصفرية. هذه البنية تجعلها مناسبة بشكل خاص لتطبيقات استرجاع المعلومات التقليدية. في معظم الحالات، يتوافق عدد الأبعاد المستخدمة في المتجهات المتفرقة مع الرموز المختلفة في لغة واحدة أو أكثر. يتم تعيين قيمة لكل بُعد تشير إلى الأهمية النسبية لهذا الرمز في المستند. يثبت هذا التصميم فائدته للمهام التي تتضمن مطابقة النصوص.
المتجهات الكثيفة: المتجهات الكثيفة هي تضمينات مشتقة من الشبكات العصبية. عند ترتيبها في مصفوفة مرتبة، تلتقط هذه المتجهات الجوهر الدلالي للنص المدخل. تجدر الإشارة إلى أن المتجهات الكثيفة لا تقتصر على معالجة النصوص؛ فهي تُستخدم أيضًا على نطاق واسع في الرؤية الحاسوبية لتمثيل دلالات البيانات المرئية. وتتميز هذه المتجهات الكثيفة، التي يتم إنشاؤها عادةً بواسطة نماذج تضمين النص، بأن معظم العناصر أو جميعها لا تساوي صفرًا. وبالتالي، تكون المتجهات الكثيفة فعالة بشكل خاص في تطبيقات البحث الدلالي، حيث يمكنها إرجاع النتائج الأكثر تشابهًا استنادًا إلى المسافة بين المتجهات حتى في حالة عدم وجود تطابق نصي دقيق. تتيح هذه الإمكانية الحصول على نتائج بحث أكثر دقة وإدراكًا للسياق، وغالبًا ما تلتقط العلاقات بين المفاهيم التي قد تغفلها الأساليب القائمة على الكلمات الرئيسية.
لمزيد من التفاصيل، راجع المتجهات المتفرقة والمتجهات الكثيفة.
البحث متعدد الوسائط
يشير البحث متعدد الوسائط إلى البحث عن تشابه البيانات غير المهيكلة عبر طرائق متعددة (مثل الصور ومقاطع الفيديو والصوت والنصوص وغيرها). على سبيل المثال، يمكن تمثيل شخص ما باستخدام طرائق مختلفة من البيانات مثل بصمات الأصابع والبصمات الصوتية وملامح الوجه. يدعم البحث الهجين عمليات بحث متعددة في وقت واحد. على سبيل المثال البحث عن شخص ببصمات أصابع وبصمات صوتية متشابهة.
سير العمل
سير العمل الرئيسي لإجراء البحث الهجين هو كما يلي.
توليد متجهات كثيفة من خلال تضمين نماذج مثل BERT و Transformers.
توليد متجهات متناثرة من خلال نماذج التضمين مثل BM25 و BGE-M3 و SPLADE وغيرها.
إنشاء مجموعة في Zilliz وتحديد مخطط المجموعة الذي يتضمن حقول المتجهات الكثيفة والمتناثرة.
أدخل المتجهات الكثيفة المتفرقة في المجموعة التي تم إنشاؤها للتو في الخطوة السابقة.
إجراء بحث هجين: سيعود البحث الهجين على المتجهات الكثيفة بمجموعة من أفضل K من النتائج الأكثر تشابهًا، كما سيعود البحث الهجين على المتجهات المتفرقة بمجموعة من أفضل K من النتائج.
التطبيع: قم بتطبيع درجات مجموعتي أعلى K من النتائج، وتحويل الدرجات إلى نطاق بين [0،1].
اختر إستراتيجية إعادة ترتيب مناسبة لدمج مجموعتي نتائج أعلى K وإعادة ترتيبها وإرجاع مجموعة نهائية من نتائج أعلى K في النهاية.
سير عمل البحث الهجين
أمثلة
سيستخدم هذا القسم مثالاً محددًا لتوضيح كيفية إجراء بحث هجين على المتجهات المتفرقة الكثيفة لتعزيز دقة عمليات البحث النصية.
إنشاء مجموعة مع حقول متجهات متعددة
تتضمن عملية إنشاء مجموعة ثلاثة أجزاء: تحديد مخطط المجموعة، وتكوين معلمات الفهرس، وإنشاء المجموعة.
تعريف المخطط
في هذا المثال، يجب تعريف حقول متجهة متعددة ضمن مخطط المجموعة. حاليًا، يمكن أن تتضمن كل مجموعة ما يصل إلى 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"
}
}
]
}'
أثناء عمليات البحث في المتجهات المتناثرة، يمكنك تبسيط عملية توليد متجهات التضمين المتناثرة من خلال الاستفادة من إمكانيات البحث في النص الكامل. لمزيد من التفاصيل، راجع البحث بالنص الكامل.
إنشاء فهرس
بعد تحديد مخطط المجموعة، من الضروري إعداد فهارس المتجهات ومقاييس التشابه. في هذا المثال، يتم إنشاء فهرس IVF_FLAT لحقل المتجهات الكثيفة dense
، ويتم إنشاء فهرس SPARSE_INVERTED_INDEX لحقل المتجهات المتفرقة sparse
. للتعرف على أنواع الفهارس المدعومة، راجع شرح الفهرس.
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 AnnSearchRequest
، وبالتالي سيتم إرجاع إجمالي 4 نتائج بحث.
تكوين استراتيجية إعادة الترتيب
لدمج وإعادة ترتيب مجموعتي نتائج بحث الشبكة النشطة ANN، من الضروري تحديد استراتيجية إعادة ترتيب مناسبة. يدعم Zilliz نوعين من استراتيجية إعادة الترتيب: استراتيجية إعادة الترتيب الموزونة واستراتيجية إعادة الترتيب RRFRanker. عند اختيار إستراتيجية إعادة الترتيب، من الأمور التي يجب أخذها بعين الاعتبار ما إذا كان هناك أي تركيز على بحث واحد أو أكثر من البحث الأساسي للشبكة العصبية الاصطناعية على حقول المتجهات.
مُرجِّح الرتبة: يوصى باستخدام هذه الاستراتيجية إذا كنت تريد أن تركز النتائج على حقل متجه معين. تسمح لك أداة WeightedRanker المرجحة بتعيين أوزان أعلى لحقول متجهة معينة، والتركيز عليها بشكل أكبر. على سبيل المثال، في عمليات البحث متعدد الوسائط، يمكن اعتبار الأوصاف النصية لصورة ما أكثر أهمية من الألوان في هذه الصورة.
RRFRanker (مصنف دمج الرتب المتبادل): يوصى بهذه الاستراتيجية عندما لا يكون هناك تركيز محدد. يمكن لـ RRRF موازنة أهمية كل حقل متجه بشكل فعال.
لمزيد من التفاصيل حول آليات هاتين الاستراتيجيتين لإعادة التصنيف، راجع إعادة التصنيف.
يشرح المثالان التاليان كيفية استخدام استراتيجيتي إعادة الترتيب المرجحة وRRRFRanker.
مثال 1: استخدام أداة إعادة الترتيب المرجحة
عند استخدام إستراتيجية WeightedRanker المرجحة، تحتاج إلى إدخال قيم الوزن في الدالة
WeightedRanker
. يتوافق عدد عمليات البحث الأساسية للشبكة العصبية الاصطناعية في البحث الهجين مع عدد القيم التي يجب إدخالها. يجب أن تكون قيم المدخلات في النطاق [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: استخدام RRFRFRanker
عند استخدام استراتيجية RRRFRanker، تحتاج إلى إدخال قيمة المعلمة
k
في RRFRanker. القيمة الافتراضية لـk
هي 60. تساعد هذه المعلمة على تحديد كيفية دمج الرتب من مختلف عمليات بحث الشبكة العنكبوتية الوطنية، بهدف موازنة ومزج الأهمية في جميع عمليات البحث.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} }'
إجراء بحث هجين
قبل إجراء بحث مختلط، من الضروري تحميل المجموعة في الذاكرة. إذا لم يكن لأي حقول متجهة في المجموعة فهرس أو لم يتم تحميلها، سيحدث خطأ عند استدعاء طريقة البحث الهجين.
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: {}']"]
بما أنه تم تحديد limit=2
في البحث الهجين، سيعيد Zilliz ترتيب نتائج البحث الأربعة من الخطوة 3 ويعيد في النهاية فقط أعلى نتيجتي بحث متشابهتين.