با حرکت پایگاههای داده برداری از تطبیق سادگی شباهت به خطوط لوله پیچیده تولید تقویتشده بازیابی (RAG)، توانایی فیلتر کردن کارآمد بردارها بر اساس متادیتا به یک گلوگاه حیاتی تبدیل شده است. بسیاری از توسعهدهندگان با افت عملکرد مواجه میشوند هنگام پرسوجو از Qdrant با فیلترهای سختگیرانه روی فیلدهای با کاردینالیته بالا، مانند شناسههای کاربر، برچسبهای زمانی یا برچسبهای خاص اسناد. در حالی که Qdrant برای سرعت طراحی شده است، جستجوی خام برداری در ترکیب با فیلترهای بهینهنشده میتواند منجر به پاسخدهی کند پرسوجوها و بار محاسباتی غیرضروری شود. کلید آزادسازی جستجوی فیلترشده با پهنای باند بالا و تأخیر کم، درک و بهرهگیری از شاخصگذاری Payload است.
چرا فیلتر کردن با کاردینالیته بالا جستجو را کند میکند
به طور پیشفرض، Qdrant ابتدا جستجوی شباهت برداری را انجام میدهد و سپس فیلترهای payload را بر روی نامزدهای حاصل اعمال میکند. این رویکرد «جستجو سپس فیلتر» برای فیلدهای با کاردینالیته پایین (مانند پرچمهای بولی یا مجموعههای کوچک دستهبندی) کارآمد است، زیرا فیلتر بخش کوچکی از نتایج را حذف میکند. با این حال، برای فیلدهای با کاردینالیته بالا—جایی که یک فیلتر ممکن است فقط با یک کسری کوچک از کل مجموعه داده مطابقت داشته باشد، یا جایی که فیلد حاوی میلیونها مقدار منحصربهفرد است—سیستم باید بردارهای بیشتری را اسکن کند تا مقدار کافی که با معیارها مطابقت دارند را پیدا کند.
بدون یک شاخص، Qdrant باید payload هر برداری که وارد مجموعه نامزدهای top-K میشود را بررسی کند تا تعیین کند آیا شرایط فیلتر را برآورده میکند یا خیر. اگر فیلتر شما محدودکننده باشد (مثلاً user_id == 12345 در یک مجموعه داده با ۱۰ میلیون بردار)، سیستم ممکن است نیاز داشته باشد هزاران بردار را بازیابی کند فقط برای یافتن تعداد کمی که هم مشابه و هم مرتبط هستند. این منجر به هزینههای I/O بالا و افزایش تأخیر میشود.
قدرت شاخصهای Payload
شاخصهای Payload به Qdrant اجازه میدهند ساختارهای داده کارآمد را برای فیلدهای خاص متادیتا از پیش محاسبه و ذخیره کند. زمانی که یک شاخص برای یک فیلد ایجاد میشود، Qdrant میتواند منطق جستجو را معکوس کند. به جای «یافتن بردارهای مشابه، سپس بررسی اینکه آیا با فیلتر مطابقت دارند»، میتواند به طور مؤثر «بردارهایی را که با فیلتر مطابقت دارند پیدا کند، سپس شباهت را درون آن زیرمجموعه بررسی کند».
برای فیلدهای با کاردینالیته بالا، Qdrant از انواع شاخص INTEGER، KEYWORD یا DATETIME استفاده میکند. این شاخصها به موتور اجازه میدهند زیرمجموعه بردارهایی که شرایط را برآورده میکنند را به سرعت شناسایی کنند و فضای جستجو را قبل از شروع محاسبات سنگین شباهت برداری به شدت کاهش دهند.
ایجاد یک شاخص در Qdrant
ایجاد یک شاخص payload از طریق API Qdrant ساده است. در اینجا نحوه شاخصگذاری یک فیلد user_id با کاردینالیته بالا در یک مجموعه به نام docs آورده شده است:
import qdrant_client
client = qdrant_client.QdrantClient(host="localhost", port=6333)
# Create an index for the 'user_id' field
# Use 'integer' for numeric IDs, 'keyword' for strings
client.create_payload_index(
collection_name="docs",
field_name="user_id",
field_schema="integer"
)
# For string-based high-cardinality fields, use keyword
client.create_payload_index(
collection_name="docs",
field_name="document_hash",
field_schema="keyword"
)
بهترین روشها برای فیلدهای با کاردینالیته بالا
همه فیلدها به یک استراتژی شاخصگذاری یکسان نیاز ندارند. به بهترین روشهای زیر توجه کنید:
- شناسایی کاردینالیته: قبل از شاخصگذاری، تعداد مقادیر منحصربهفرد را تخمین بزنید. اگر یک فیلد دارای کاردینالیته پایین باشد (مثلاً "status": ["active", "inactive"]), یک فیلتر payload استاندارد اغلب به دلیل هزینههای نگهداری شاخص کمتر، کافی و سریعتر است. شاخصهای payload را برای فیلدهایی با هزاران یا میلیونها مقدار منحصربهفرد رزرو کنید.
- استفاده از نوع Schema صحیح: همیشه
field_schemaصحیح را مشخص کنید. استفاده ازkeywordبرای متن طولانی یا رشتههای غیرساختاریافته منجر به عملکرد ضعیف میشود. ازintegerیاfloatبرای دادههای عددی وdatetimeبرای فیلتر کردن سریهای زمانی استفاده کنید. - پایش اندازه شاخص: شاخصهای payload فضای ذخیرهسازی اضافی مصرف میکنند. برای مجموعههای بسیار بزرگ با فیلدهای متعدد با کاردینالیته بالا، اندازه کل شاخص را پایش کنید تا اطمینان حاصل شود که در مقایسه با زیرساخت شما قابل مدیریت باقی میماند.
- ترکیب با بردارهای پراکنده: در سیستمهای RAG پیچیده، ترکیب جستجوی برداری متراکم با جستجوی برداری پراکنده (برای تطبیق کلمات کلیدی) و فیلتر کردن payload گاهی اوقات عملکرد بهتری نسبت به رویکردهای کاملاً متراکم + فیلتر دارد، به ویژه زمانی که فیلتر بسیار محدودکننده باشد.
مثال عملی: فیلتر کردن بر اساس کاربر و زمان
تصور کنید یک هوش مصنوعی پشتیبانی مشتری که بردارهای تاریخچه چت را ذخیره میکند. شما نیاز دارید ۵ تعامل گذشته مشابهترین را برای user_id 999 که در ۷ روز گذشته رخ دادهاند، بازیابی کنید.
بدون شاخصها، Qdrant به طور سراسری به دنبال بردارهای مشابه میگشت و آنها را یکییکی فیلتر میکرد. با شاخصها روی user_id (عدد صحیح) و timestamp (تاریخ و زمان)، Qdrant میتواند ابتدا محدوده جستجو را به بردارهایی که متعلق به کاربر 999 هستند و در بازه زمانی قرار دارند محدود کند، سپس فقط روی آن مجموعه کاهشیافته رتبهبندی شباهت را انجام دهد.
from qdrant_client import models
import time
# Define the filter condition
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 days ago
lte=time.time()
)
)
]
)
# Execute search
results = client.search(
collection_name="chat_history",
query_vector=[0.1, 0.2, 0.3, ...], # Your embedding
query_filter=filter_query,
limit=5
)
# Results are now guaranteed to be both similar and filtered
for point in results:
print(f"Score: {point.score}, ID: {point.id}")
نتیجهگیری
بهینهسازی جستجوی برداری فیلترشده در Qdrant فقط درباره نوشتن پرسوجوی درست نیست؛ بلکه درباره آمادهسازی ساختار داده برای پشتیبانی کارآمد از آن پرسوجو است. با شناسایی فیلدهای متادیتای با کاردینالیته بالا و اعمال شاخصهای payload مناسب، شما اسکنهای احتمالی کند و جامع را به جستجوهای هدفمند و سریع تبدیل میکنید. برای توسعهدهندگان متوسط تا پیشرفته که سیستمهای RAG درجه تولید را میسازند، تسلط بر شاخصگذاری payload برای ارائه تجربیات بازیابی با تأخیر کم و دقیق در مقیاس بزرگ ضروری است. همیشه پرسوجوهای خود را با و بدون شاخصها پروفایل کنید تا تأثیر آن را درک کنید و به یاد داشته باشید که هدف، به حداقل رساندن فضای جستجو قبل از شروع محاسبه شباهت برداری است.