🚀 جرب Zilliz Cloud، الـ Milvus المدارة بالكامل، مجاناً — تجربة أداء أسرع بـ 10 أضعاف! جرب الآن>>

milvus-logo
LFAI
الصفحة الرئيسية
  • دليل المستخدم
  • Home
  • Docs
  • دليل المستخدم

  • البحث وإعادة التصنيف

  • بحث مصفى

البحث المصفى

يعثر بحث ANN على التضمينات المتجهة الأكثر تشابهًا مع التضمينات المتجهة المحددة. ومع ذلك، قد لا تكون نتائج البحث صحيحة دائماً. يمكنك تضمين شروط التصفية في طلب البحث بحيث يقوم ميلفوس بإجراء تصفية للبيانات الوصفية قبل إجراء عمليات بحث الشبكة النانوية المتجهة، مما يقلل من نطاق البحث من المجموعة بأكملها إلى الكيانات المطابقة لشروط التصفية المحددة فقط.

نظرة عامة

في ميلفوس، يتم تصنيف عمليات البحث التي تمت تصفيتها إلى نوعين - التصفية القياسية والتصفية التكرارية - اعتمادًا على المرحلة التي يتم فيها تطبيق التصفية.

التصفية القياسية

إذا كانت المجموعة تحتوي على كل من التضمينات المتجهة والبيانات الوصفية الخاصة بها، يمكنك تصفية البيانات الوصفية قبل البحث في ANN لتحسين ملاءمة نتيجة البحث. بمجرد أن يتلقى ميلفوس طلب بحث يحمل شرط تصفية، فإنه يقيد نطاق البحث ضمن الكيانات المطابقة لشرط التصفية المحدد.

Filtered search البحث المصفى

كما هو موضح في الرسم البياني أعلاه، يحمل طلب البحث chunk like % red % كشرط تصفية، مما يشير إلى أن ميلفوس يجب أن يجري بحث الشبكة النانوية ضمن جميع الكيانات التي تحتوي على كلمة red في الحقل chunk. على وجه التحديد، يقوم ميلفوس بما يلي.

  • تصفية الكيانات التي تطابق شروط التصفية الواردة في طلب البحث.

  • إجراء بحث ANN داخل الكيانات التي تمت تصفيتها.

  • إرجاع الكيانات الأعلى-K.

التصفية التكرارية

تقوم عملية التصفية القياسية بتضييق نطاق البحث بشكل فعال إلى نطاق صغير. ومع ذلك، قد تؤدي تعابير التصفية المعقدة بشكل مفرط إلى زمن بحث مرتفع للغاية. في مثل هذه الحالات، يمكن أن تعمل التصفية التكرارية كبديل، مما يساعد على تقليل عبء العمل في التصفية التكرارية.

Iterative filtering التصفية التكرارية

كما هو موضح في الرسم البياني أعلاه، يقوم البحث باستخدام التصفية التكرارية بإجراء البحث المتجه في تكرارات. يخضع كل كيان يتم إرجاعه بواسطة المكرر لتصفية عددية، وتستمر هذه العملية حتى يتم تحقيق أعلى عدد محدد من النتائج.

تقلل هذه الطريقة بشكل كبير من عدد الكيانات الخاضعة للتصفية القياسية، مما يجعلها مفيدة بشكل خاص للتعامل مع تعبيرات التصفية شديدة التعقيد.

ومع ذلك، من المهم ملاحظة أن المُكرِّر يعالج الكيانات واحدًا تلو الآخر. يمكن أن يؤدي هذا النهج المتسلسل إلى أوقات معالجة أطول أو مشاكل محتملة في الأداء، خاصةً عندما يخضع عدد كبير من الكيانات للتصفية العددية.

أمثلة

يوضح هذا القسم كيفية إجراء بحث مصفى. تفترض مقتطفات التعليمات البرمجية في هذا القسم أن لديك بالفعل الكيانات التالية في مجموعتك. يحتوي كل كيان على أربعة حقول، وهي المعرف والمتجه واللون والإعجابات.

[
    {"id": 0, "vector": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592], "color": "pink_8682", "likes": 165},
    {"id": 1, "vector": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104], "color": "red_7025", "likes": 25},
    {"id": 2, "vector": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, 0.7894058910881185, 0.20785793220625592], "color": "orange_6781", "likes": 764},
    {"id": 3, "vector": [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995, 0.95791889146345], "color": "pink_9298", "likes": 234},
    {"id": 4, "vector": [0.4452349528804562, -0.8757026943054742, 0.8220779437047674, 0.46406290649483184, 0.30337481143159106], "color": "red_4794", "likes": 122},
    {"id": 5, "vector": [0.985825131989184, -0.8144651566660419, 0.6299267002202009, 0.1206906911183383, -0.1446277761879955], "color": "yellow_4222", "likes": 12},
    {"id": 6, "vector": [0.8371977790571115, -0.015764369584852833, -0.31062937026679327, -0.562666951622192, -0.8984947637863987], "color": "red_9392", "likes": 58},
    {"id": 7, "vector": [-0.33445148015177995, -0.2567135004164067, 0.8987539745369246, 0.9402995886420709, 0.5378064918413052], "color": "grey_8510", "likes": 775},
    {"id": 8, "vector": [0.39524717779832685, 0.4000257286739164, -0.5890507376891594, -0.8650502298996872, -0.6140360785406336], "color": "white_9381", "likes": 876},
    {"id": 9, "vector": [0.5718280481994695, 0.24070317428066512, -0.3737913482606834, -0.06726932177492717, -0.6980531615588608], "color": "purple_4976", "likes": 765}
]

البحث باستخدام التصفية القياسية

توضح المقتطفات البرمجية التالية بحثًا بتصفية قياسية، والطلب في المقتطف البرمجي التالي يحمل شرط تصفية وعدة حقول إخراج.

from pymilvus import MilvusClient

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

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

res = client.search(
    collection_name="my_collection",
    data=[query_vector],
    limit=5,
    # highlight-start
    filter='color like "red%" and likes > 50',
    output_fields=["color", "likes"]
    # highlight-end
)

for hits in res:
    print("TopK results:")
    for hit in hits:
        print(hit)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp

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

FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
        .collectionName("filtered_search_collection")
        .data(Collections.singletonList(queryVector))
        .topK(5)
        .filter("color like \"red%\" and likes > 50")
        .outputFields(Arrays.asList("color", "likes"))
        .build();

SearchResp searchResp = client.search(searchReq);

List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
    System.out.println("TopK results:");
    for (SearchResp.SearchResult result : results) {
        System.out.println(result);
    }
}

// Output
// TopK results:
// SearchResp.SearchResult(entity={color=red_4794, likes=122}, score=0.5975797, id=4)
// SearchResp.SearchResult(entity={color=red_9392, likes=58}, score=-0.24996188, id=6)

import (
    "context"
    "log"

    "github.com/milvus-io/milvus/client/v2"
    "github.com/milvus-io/milvus/client/v2/entity"
)

func ExampleClient_Search_filter() {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()

        milvusAddr := "127.0.0.1:19530"
        token := "root:Milvus"

        cli, err := client.New(ctx, &client.ClientConfig{
                Address: milvusAddr,
                APIKey:  token,
        })
        if err != nil {
                log.Fatal("failed to connect to milvus server: ", err.Error())
        }

        defer cli.Close(ctx)

        queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}

        resultSets, err := cli.Search(ctx, client.NewSearchOption(
                "filtered_search_collection", // collectionName
                3,             // limit
                []entity.Vector{entity.FloatVector(queryVector)},
        ).WithFilter(`color like "red%" and likes > 50`).WithOutputFields("color", "likes"))
        if err != nil {
                log.Fatal("failed to perform basic ANN search collection: ", err.Error())
        }

        for _, resultSet := range resultSets {
                log.Println("IDs: ", resultSet.IDs)
                log.Println("Scores: ", resultSet.Scores)
        }
        // Output:
        // IDs:
        // Scores:
}


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

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

const query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

const res = await client.search({
    collection_name: "filtered_search_collection",
    data: [query_vector],
    limit: 5,
    // highlight-start
    filters: 'color like "red%" and likes > 50',
    output_fields: ["color", "likes"]
    // highlight-end
})

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "quick_setup",
    "data": [
        [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
    ],
    "annsField": "vector",
    "filter": "color like \"red%\" and likes > 50",
    "limit": 3,
    "outputFields": ["color", "likes"]
}'
# {"code":0,"cost":0,"data":[]}

يقرأ شرط التصفية المحمول في طلب البحث color like "red%" and likes > 50. ويستخدم العامل "و" لتضمين شرطين: الأول يطلب الكيانات التي لها قيمة تبدأ بـ red في الحقل color ، والآخر يطلب الكيانات التي لها قيمة أكبر من 50 في الحقل likes. هناك كيانان فقط يستوفيان هذين الشرطين. مع تعيين أعلى K على 3 ، سيقوم ميلفوس بحساب المسافة بين هذين الكيانين إلى متجه الاستعلام وإعادتهما كنتيجة للبحث.

[
    {
        "id": 4, 
        "distance": 0.3345786594834839,
        "entity": {
            "vector": [0.4452349528804562, -0.8757026943054742, 0.8220779437047674, 0.46406290649483184, 0.30337481143159106], 
            "color": "red_4794", 
            "likes": 122
        }
    },
    {
        "id": 6, 
        "distance": 0.6638239834383389"entity": {
            "vector": [0.8371977790571115, -0.015764369584852833, -0.31062937026679327, -0.562666951622192, -0.8984947637863987], 
            "color": "red_9392", 
            "likes": 58
        }
    },
]

لمزيد من المعلومات حول العوامل التي يمكنك استخدامها في تصفية البيانات الوصفية، راجع تصفية البيانات الوصفية.

البحث باستخدام التصفية التكرارية

لإجراء بحث مصفى باستخدام التصفية التكرارية، يمكنك القيام بما يلي:

from pymilvus import MilvusClient

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

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

res = client.search(
    collection_name="my_collection",
    data=[query_vector],
    limit=5,
    # highlight-start
    filter='color like "red%" and likes > 50',
    output_fields=["color", "likes"],
    search_params={
        "hints": "iterative_filter"
    }    
    # highlight-end
)

for hits in res:
    print("TopK results:")
    for hit in hits:
        print(hit)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;

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

FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
        .collectionName("filtered_search_collection")
        .data(Collections.singletonList(queryVector))
        .topK(5)
        .filter("color like \"red%\" and likes > 50")
        .outputFields(Arrays.asList("color", "likes"))
        .searchParams(new HashMap<>("hints", "iterative_filter"))
        .build();

SearchResp searchResp = client.search(searchReq);

List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
    System.out.println("TopK results:");
    for (SearchResp.SearchResult result : results) {
        System.out.println(result);
    }
}

// Output
// TopK results:
// SearchResp.SearchResult(entity={color=red_4794, likes=122}, score=0.5975797, id=4)
// SearchResp.SearchResult(entity={color=red_9392, likes=58}, score=-0.24996188, id=6)

import (
    "context"
    "log"

    "github.com/milvus-io/milvus/client/v2"
    "github.com/milvus-io/milvus/client/v2/entity"
)

func ExampleClient_Search_filter() {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()

        milvusAddr := "127.0.0.1:19530"
        token := "root:Milvus"

        cli, err := client.New(ctx, &client.ClientConfig{
                Address: milvusAddr,
                APIKey:  token,
        })
        if err != nil {
                log.Fatal("failed to connect to milvus server: ", err.Error())
        }

        defer cli.Close(ctx)

        queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}

        resultSets, err := cli.Search(ctx, client.NewSearchOption(
                "filtered_search_collection", // collectionName
                3,             // limit
                []entity.Vector{entity.FloatVector(queryVector)},
        ).WithFilter(`color like "red%" and likes > 50`).WithHints("iterative_filter").WithOutputFields("color", "likes"))
        if err != nil {
                log.Fatal("failed to perform basic ANN search collection: ", err.Error())
        }

        for _, resultSet := range resultSets {
                log.Println("IDs: ", resultSet.IDs)
                log.Println("Scores: ", resultSet.Scores)
        }
        // Output:
        // IDs:
        // Scores:
}


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

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

const query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

const res = await client.search({
    collection_name: "filtered_search_collection",
    data: [query_vector],
    limit: 5,
    // highlight-start
    filters: 'color like "red%" and likes > 50',
    hints: "iterative_filter",
    output_fields: ["color", "likes"]
    // highlight-end
})

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "quick_setup",
    "data": [
        [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
    ],
    "annsField": "vector",
    "filter": "color like \"red%\" and likes > 50",
    "searchParams": {"hints": "iterative_filter"},
    "limit": 3,
    "outputFields": ["color", "likes"]
}'
# {"code":0,"cost":0,"data":[]}

جرب Managed Milvus مجاناً

Zilliz Cloud خالي من المتاعب، ويعمل بواسطة Milvus ويعمل بسرعة 10 أضعاف.

ابدأ
التعليقات

هل كانت هذه الصفحة مفيدة؟