Vector Databases

Qdrant Yüklem Dizinleme: Yüksek Kardinaliteli Veri Metaları İçin Filtrelenmiş Vektör Aramasını Optimize Etme

Vektör veritabanları basit benzerlik eşleştirmesinden karmaşık Geri Getirme Destekli Üretim (RAG) hatlarına geçtikçe, vektörleri veri metalarına göre verimli bir şekilde filtreleme yeteneği kritik bir darboğaza dönüşmüştür. Birçok geliştirici, Qdrant'a kullanıcı kimlikleri, zaman damgaları veya belirli belge etiketleri gibi yüksek kardinaliteli alanlarda sıkı filtrelerle sorgu yaptığında performans düşüşüyle karşılaşır. Qdrant hız için tasarlanmış olsa da, ham vektör araması ile optimize edilmemiş filtreleme birleşimi, yavaş sorgu yanıtlarına ve gereksiz hesaplama yüküne yol açabilir. Yüksek verimli, düşük gecikmeli filtreli aramanın kilidini açmanın anahtarı, Yüklem Dizinlemeyi (Payload Indexing) anlamak ve kullanmaktır.

Neden Yüksek Kardinaliteli Filtreleme Aramayı Yavaşlatır?

Varsayılan olarak Qdrant, önce vektör benzerlik aramasını gerçekleştirir ve ardından sonuçlanan adaylara yüklem filtrelerini uygular. Bu "önce ara, sonra filtrele" yaklaşımı, düşük kardinaliteli alanlar için (örneğin boole bayrakları veya küçük kategori kümeleri) verimlidir, çünkü filtre sonuçların küçük bir bölümünü eleyerek işe yarar. Ancak, bir filtresin tüm veri setinin yalnızca küçük bir kısmıyla eşleşebileceği veya alanın milyonlarca benzersiz değer içerebileceği yüksek kardinaliteli alanlar için, sistem kriterlere uyan yeterli sayıda vektörü bulmak için daha fazla vektörü taramak zorundadır.

Bir dizin olmadan, Qdrant'ın filtre koşullarını karşılayıp karşılamadığını belirlemek için üst-K aday kümesine giren her vektörün yüklemine (payload) bakması gerekir. Filtreniz kısıtlayıcıysa (örneğin, 10 milyon vektörlük bir veri setinde user_id == 12345), sistem hem benzer hem de ilgili olan birkaç vektörü bulmak için binlerce vektörü getirmek zorunda kalabilir. Bu durum yüksek G/Ç (I/O) maliyetlerine ve artan gecikmeye neden olur.

Yüklem Dizinlerinin Gücü

Yüklem dizinleri, Qdrant'ın belirli veri metası alanları için verimli veri yapılarını önceden hesaplamasına ve saklamasına olanak tanır. Bir alan için bir dizin oluşturulduğunda, Qdrant arama mantığını tersine çevirebilir. Bunun yerine "benzer vektörleri bul, sonra filtreyle eşleşip eşleşmediklerini kontrol et" yerine, etkili bir şekilde "filtreyle eşleşen vektörleri bul, sonra o alt küme içinde benzerliği kontrol et" yapabilir.

Yüksek kardinaliteli alanlar için Qdrant, INTEGER, KEYWORD veya DATETIME dizin türlerini kullanır. Bu dizinler, motorun koşulu sağlayan vektör alt kümesini hızla bulmasını sağlar ve vektör benzerlik hesabının ağır işi başlamadan önce arama alanını dramatik bir şekilde daraltır.

Qdrant'ta Bir Dizin Oluşturma

Qdrant API'si aracılığıyla bir yüklem dizini oluşturmak basittir. docs adlı bir koleksiyonda yüksek kardinaliteli bir user_id alanını nasıl dizinleyebileceğiniz aşağıda gösterilmektedir:

import qdrant_client

client = qdrant_client.QdrantClient(host="localhost", port=6333)

# 'user_id' alanı için bir dizin oluşturun
# Sayısal kimlikler için 'integer', dizeler için 'keyword' kullanın
client.create_payload_index(
    collection_name="docs",
    field_name="user_id",
    field_schema="integer"
)

# Dize tabanlı yüksek kardinaliteli alanlar için keyword kullanın
client.create_payload_index(
    collection_name="docs",
    field_name="document_hash",
    field_schema="keyword"
)

Yüksek Kardinaliteli Alanlar İçin En İyi Uygulamalar

Tüm alanlar aynı dizinleme stratejisini gerektirmez. Aşağıdaki en iyi uygulamaları göz önünde bulundurun:

  • Kardinaliteyi Belirleyin: Dizinlemeden önce benzersiz değer sayısını tahmin edin. Bir alanın düşük kardinaliteye sahip olması durumunda (örneğin, "status": ["active", "inactive"]), daha düşük dizin bakım maliyetleri nedeniyle standart bir yüklem filtresi genellikle yeterlidir ve daha hızlıdır. Yüklem dizinlerini, binlerce veya milyonlarca benzersiz değere sahip alanlar için saklayın.
  • Doğru Şema Türünü Kullanın: Her zaman doğru field_schema'yı belirtin. Uzun metinler veya yapılandırılmamış diziler için keyword kullanmak kötü performansa yol açar. Sayısal veriler için integer veya float, zaman serisi filtreleme için ise datetime kullanın.
  • Dizin Boyutunu İzleyin: Yüklem dizinleri ek depolama alanı tüketir. Çok sayıda yüksek kardinaliteli alana sahip çok büyük koleksiyonlar için, dizin boyutunun altyapınıza göre yönetilebilir kalmasını sağlamak için toplam dizin boyutunu izleyin.
  • Sparse Vektörlerle Birleştirin: Karmaşık RAG sistemlerinde, yoğun vektör aramasını, seyrek vektör araması (anahtar kelime eşleştirmesi için) ve yüklem filtreleme ile birleştirmek, özellikle filtre son derece kısıtlayıcı olduğunda, saf yoğun + filtre yaklaşımlarından daha iyi performans gösterebilir.

Pratik Örnek: Kullanıcı ve Zaman Göre Filtreleme

Sohbet geçmişi vektörlerini saklayan bir müşteri destek yapay zekası hayal edin. user_id 999 için son 7 gün içinde gerçekleşen en benzer 5 geçmiş etkileşimi getirmeniz gerekiyor.

Dizinler olmadan, Qdrant benzer vektörleri küresel olarak arar ve onları tek tek filtrelerdi. user_id (integer) ve timestamp (datetime) üzerinde dizinlerle, Qdrant önce arama kapsamını yalnızca 999 numaralı kullanıcıya ait ve zaman aralığına uyan vektörlere daraltabilir, ardından benzerlik sıralamasını yalnızca bu küçültülmüş küme üzerinde gerçekleştirebilir.

from qdrant_client import models
import time

# Filtre koşulunu tanımlayın
filter_query = models.Filter(
    must=[
        models.FieldCondition(
            key="user_id",
            match=models.MatchValue(value=999)
        ),
        models.FieldCondition(
            key="timestamp",
            range=models.Range(
                gte=time.time() - (7 * 24 * 60 * 60), # 7 gün önce
                lte=time.time()
            )
        )
    ]
)

# Aramayı çalıştırın
results = client.search(
    collection_name="chat_history",
    query_vector=[0.1, 0.2, 0.3, ...], # Gömme (embedding) vektörünüz
    query_filter=filter_query,
    limit=5
)

# Sonuçlar artık hem benzer hem de filtrelenmiş olarak garanti edilir
for point in results:
    print(f"Score: {point.score}, ID: {point.id}")

Sonuç

Qdrant'ta filtrelenmiş vektör aramasını optimize etmek, doğru sorguyu yazmaktan çok daha fazlasıdır; bu, o sorguyu verimli bir şekilde desteklemek için veri yapısını hazırlamaktır. Yüksek kardinaliteli veri metası alanlarını belirleyerek ve uygun yüklem dizinlerini uygulayarak, potansiyel olarak yavaş ve kapsamlı taramaları hedefli ve hızlı aramalara dönüştürürsünüz. Üretim düzeyinde RAG sistemleri geliştiren orta düzeyden ileri düzey geliştiriciler için, ölçekli düşük gecikmeli ve doğru geri getirme deneyimleri sunmak için yüklem dizinlemesini ustalaşmak esastır. Etkiyi anlamak için sorgularınızı her zaman dizinlerle ve dizinsiz olarak profilleyin ve vektör benzerlik hesabı başlamadan önce arama alanını en aza indirmenin hedef olduğunu unutmayın.

Share: