🚀 Coba Zilliz Cloud, Milvus yang sepenuhnya terkelola, secara gratis—rasakan performa 10x lebih cepat! Coba Sekarang>>

milvus-logo
LFAI
Beranda
  • Panduan Pengguna
  • Home
  • Docs
  • Panduan Pengguna

  • Cari & Beri Peringkat Ulang

  • Pencarian yang Difilter

Pencarian yang Difilter

Pencarian ANN menemukan penyematan vektor yang paling mirip dengan penyematan vektor yang ditentukan. Namun, hasil pencarian mungkin tidak selalu benar. Anda dapat menyertakan kondisi pemfilteran dalam permintaan pencarian sehingga Milvus melakukan pemfilteran metadata sebelum melakukan pencarian ANN, sehingga mengurangi cakupan pencarian dari seluruh koleksi menjadi hanya entitas yang sesuai dengan kondisi pemfilteran yang ditentukan.

Gambaran Umum

Di Milvus, penyaringan pencarian dikategorikan ke dalam dua jenis - penyaringan standar dan penyaringan berulang - tergantung pada tahap penyaringan yang diterapkan.

Pemfilteran Standar

Jika koleksi berisi penyematan vektor dan metadatanya, Anda dapat memfilter metadata sebelum pencarian ANN untuk meningkatkan relevansi hasil pencarian. Setelah Milvus menerima permintaan pencarian yang berisi kondisi pemfilteran, Milvus akan membatasi cakupan pencarian di dalam entitas yang sesuai dengan kondisi pemfilteran yang ditentukan.

Filtered search Pencarian yang difilter

Seperti yang ditunjukkan pada diagram di atas, permintaan pencarian membawa chunk like % red % sebagai kondisi pemfilteran, yang menunjukkan bahwa Milvus harus melakukan pencarian ANN di dalam semua entitas yang memiliki kata red di bidang chunk. Secara khusus, Milvus melakukan hal berikut.

  • Menyaring entitas yang sesuai dengan kondisi penyaringan yang dibawa dalam permintaan pencarian.

  • Melakukan pencarian ANN di dalam entitas yang difilter.

  • Mengembalikan entitas top-K.

Pemfilteran Iteratif

Proses pemfilteran standar secara efektif mempersempit cakupan pencarian ke kisaran kecil. Namun, ekspresi pemfilteran yang terlalu rumit dapat menghasilkan latensi pencarian yang sangat tinggi. Dalam kasus seperti itu, pemfilteran berulang dapat berfungsi sebagai alternatif, membantu mengurangi beban kerja pemfilteran skalar.

Iterative filtering Pemfilteran berulang

Seperti yang diilustrasikan pada diagram di atas, pencarian dengan penyaringan berulang melakukan pencarian vektor dalam beberapa kali iterasi. Setiap entitas yang dikembalikan oleh iterator mengalami pemfilteran skalar, dan proses ini terus berlanjut hingga hasil topK yang ditentukan tercapai.

Metode ini secara signifikan mengurangi jumlah entitas yang mengalami pemfilteran skalar, sehingga sangat bermanfaat untuk menangani ekspresi pemfilteran yang sangat kompleks.

Namun, penting untuk dicatat bahwa iterator memproses entitas satu per satu. Pendekatan berurutan ini dapat menyebabkan waktu pemrosesan yang lebih lama atau potensi masalah kinerja, terutama ketika sejumlah besar entitas mengalami pemfilteran skalar.

Contoh

Bagian ini mendemonstrasikan cara melakukan pencarian yang difilter. Cuplikan kode di bagian ini mengasumsikan Anda telah memiliki entitas berikut dalam koleksi Anda. Setiap entitas memiliki empat bidang, yaitu id, vektor, warna, dan suka.

[
    {"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}
]

Pencarian dengan Pemfilteran Standar

Cuplikan kode berikut ini mendemonstrasikan pencarian dengan pemfilteran standar, dan permintaan dalam cuplikan kode berikut ini membawa kondisi pemfilteran dan beberapa bidang keluaran.

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":[]}

Kondisi pemfilteran yang dibawa dalam permintaan pencarian berbunyi color like "red%" and likes > 50. Ia menggunakan operator and untuk menyertakan dua kondisi: kondisi pertama meminta entitas yang memiliki nilai yang dimulai dengan red pada kolom color, dan kondisi kedua meminta entitas dengan nilai yang lebih besar dari 50 pada kolom likes. Hanya ada dua entitas yang memenuhi persyaratan ini. Dengan setelan top-K ke 3, Milvus akan menghitung jarak antara dua entitas ini ke vektor kueri dan mengembalikannya sebagai hasil pencarian.

[
    {
        "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
        }
    },
]

Untuk informasi lebih lanjut tentang operator yang dapat Anda gunakan dalam pemfilteran metadata, lihat Pemfilteran Metadata.

Mencari dengan pemfilteran iteraif

Untuk melakukan pencarian yang difilter dengan pemfilteran berulang, Anda dapat melakukan hal berikut:

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":[]}

Coba Milvus yang Dikelola secara Gratis

Zilliz Cloud bebas masalah, didukung oleh Milvus dan 10x lebih cepat.

Mulai
Umpan balik

Apakah halaman ini bermanfaat?