Bộ lọc
Với Qdrant, bạn có thể đặt điều kiện tìm kiếm hoặc truy xuất điểm, điều này có nghĩa là bạn có thể lọc theo thuộc tính ngoài việc tìm kiếm tương đồng cho các vector, tương tự như việc thiết lập các điều kiện SQL where
. Ví dụ, bạn có thể đặt điều kiện cho dữ liệu đầu vào và id
của điểm.
Quan trọng là phải đặt điều kiện bổ sung khi không phải tất cả các tính năng của một đối tượng có thể được biểu thị trong một embedding. Ví dụ, các yêu cầu kinh doanh khác nhau như sẵn có hàng tồn kho, vị trí người dùng hoặc dải giá dự kiến.
Điều kiện Bộ lọc
Qdrant cho phép bạn kết hợp các điều kiện trong các mệnh đề. Các mệnh đề là các hoạt động logic khác nhau, chẳng hạn như OR
, AND
, và NOT
. Các mệnh đề có thể được lồng vào nhau theo cách đệ quy, vì vậy bạn có thể tái tạo bất kỳ biểu thức logic nào.
Hãy xem các mệnh đề được thực hiện trong Qdrant.
Giả sử chúng ta có một tập hợp các điểm với dữ liệu đầu vào:
[
{ "id": 1, "city": "London", "color": "green" },
{ "id": 2, "city": "London", "color": "red" },
{ "id": 3, "city": "London", "color": "blue" },
{ "id": 4, "city": "Berlin", "color": "red" },
{ "id": 5, "city": "Moscow", "color": "green" },
{ "id": 6, "city": "Moscow", "color": "blue" }
]
Bắt buộc
Ví dụ:
POST /collections/{tên_bộ_sưu_tập}/points/scroll
{
"filter": {
"must": [
{ "key": "city", "match": { "value": "London" } },
{ "key": "color", "match": { "value": "red" } }
]
}
...
}
Các điểm đã lọc sẽ là:
[{ "id": 2, "city": "London", "color": "red" }]
Khi sử dụng must
, mệnh đề là đúng
chỉ khi mỗi điều kiện được liệt kê trong must
được thỏa mãn. Theo cách này, must
tương đương với toán tử AND
.
Nên
Nên
tương tự như toán tử OR
trong SQL.
Ví dụ:
POST /collections/{tên_bộ_sưu_tập}/points/scroll
{
"filter": {
"should": [
{ "key": "city", "match": { "value": "London" } },
{ "key": "color", "match": { "value": "red" } }
]
}
...
}
Các điểm đã lọc sẽ là:
[
{ "id": 1, "city": "London", "color": "green" },
{ "id": 2, "city": "London", "color": "red" },
{ "id": 3, "city": "London", "color": "blue" },
{ "id": 4, "city": "Berlin", "color": "red" }
]
Khi sử dụng should
, mệnh đề là đúng
miễn là ít nhất một điều kiện được liệt kê trong should
được thỏa mãn. Theo cách này, should
tương đương với toán tử OR
.
must_not
Ví dụ:
POST /collections/{tên_bộ_sưu_tập}/points/scroll
{
"filter": {
"must_not": [
{ "key": "city", "match": { "value": "London" } },
{ "key": "color", "match": { "value": "red" } }
]
}
...
}
Các điểm đã lọc sẽ là:
[
{ "id": 5, "city": "Moscow", "color": "green" },
{ "id": 6, "city": "Moscow", "color": "blue" }
]
Khi sử dụng must_not
, mệnh đề con là đúng
chỉ khi không có điều kiện nào được liệt kê trong must_not
được thỏa mãn. Theo cách này, must_not
tương đương với biểu thức (NOT A) AND (NOT B) AND (NOT C)
.
Kết hợp Các Điều Kiện
Có thể sử dụng đồng thời nhiều điều kiện:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{ "key": "city", "match": { "value": "London" } }
],
"must_not": [
{ "key": "color", "match": { "value": "red" } }
]
}
...
}
Các điểm đã được lọc sẽ là:
[
{ "id": 1, "city": "London", "color": "green" },
{ "id": 3, "city": "London", "color": "blue" }
]
Trong trường hợp này, các điều kiện được kết hợp bằng cách sử dụng "AND".
Ngoài ra, các điều kiện có thể được lồng nhau theo cách đệ quy. Ví dụ:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must_not": [
{
"must": [
{ "key": "city", "match": { "value": "London" } },
{ "key": "color", "match": { "value": "red" } }
]
}
]
}
...
}
Các điểm đã được lọc sẽ là:
[
{ "id": 1, "city": "London", "color": "green" },
{ "id": 3, "city": "London", "color": "blue" },
{ "id": 4, "city": "Berlin", "color": "red" },
{ "id": 5, "city": "Moscow", "color": "green" },
{ "id": 6, "city": "Moscow", "color": "blue" }
]
Lọc Điều Kiện
Trong dữ liệu đầu vào, các loại giá trị khác nhau tương ứng với các loại truy vấn khác nhau có thể áp dụng cho chúng. Hãy xem xét các biến thể điều kiện hiện có và các loại dữ liệu mà chúng áp dụng.
Phù hợp
{
"key": "color",
"match": {
"value": "red"
}
}
Đối với các loại khác, các điều kiện phù hợp trông giống nhau, chỉ khác về loại dữ liệu được sử dụng:
{
"key": "count",
"match": {
"value": 0
}
}
Điều kiện đơn giản nhất kiểm tra xem giá trị lưu trữ có bằng với giá trị được cung cấp không. Nếu có nhiều giá trị được lưu trữ, ít nhất một trong số chúng phải thỏa mãn điều kiện. Điều này có thể áp dụng cho dữ liệu từ khóa, số nguyên và boolean.
Bất kỳ Phù Hợp
Có sẵn từ phiên bản v1.1.0 trở lên
Nếu bạn muốn kiểm tra xem giá trị được lưu trữ có thuộc một trong nhiều giá trị, bạn có thể sử dụng điều kiện bất kỳ phù hợp. Bất kỳ phù hợp xem xét giá trị được cung cấp như là một phép toán OR logic. Nó cũng có thể được mô tả như toán tử IN
.
Bạn có thể áp dụng nó cho dữ liệu từ khóa và số nguyên.
Ví dụ:
{
"key": "color",
"match": {
"any": ["black", "yellow"]
}
}
Trong ví dụ này, nếu giá trị được lưu trữ là black
hoặc yellow
, thì điều kiện sẽ được thỏa mãn.
Nếu giá trị được lưu trữ là một mảng, nó phải có ít nhất một giá trị khớp với bất kỳ giá trị nào đã cho. Ví dụ, nếu giá trị được lưu trữ là ["black", "green"]
, thì điều kiện sẽ được thỏa mãn vì "black"
nằm trong ["black", "yellow"]
.
Loại Trừ Phù Hợp
Có sẵn từ phiên bản v1.2.0 trở lên
Nếu bạn muốn kiểm tra xem giá trị được lưu trữ không phải là một trong nhiều giá trị, bạn có thể sử dụng điều kiện loại trừ phù hợp. Loại trừ phù hợp xem xét giá trị được cung cấp như là một phép toán NOR logic. Nó cũng có thể được mô tả như toán tử NOT IN
.
Bạn có thể áp dụng nó cho dữ liệu từ khóa và số nguyên.
Ví dụ:
{
"key": "color",
"match": {
"except": ["black", "yellow"]
}
}
Trong ví dụ này, nếu giá trị được lưu trữ không phải là black
hoặc yellow
, thì điều kiện sẽ được thỏa mãn.
Nếu giá trị được lưu trữ là một mảng, nó phải có ít nhất một giá trị không khớp với bất kỳ giá trị nào đã cho. Ví dụ, nếu giá trị được lưu trữ là ["black", "green"]
, thì điều kiện sẽ được thỏa mãn vì "green"
không khớp với "black"
hoặc "yellow"
.
Khóa Lồng Nạp
Có sẵn từ phiên bản v1.1.0 trở lên
Vì dữ liệu đầu vào là một đối tượng JSON tùy ý, bạn có thể cần lọc các trường lồng nạp.
Để tiện lợi, chúng tôi sử dụng cú pháp tương tự như dự án Jq.
Giả sử chúng ta có một tập hợp các điểm với dữ liệu đầu vào như sau:
[
{
"id": 1,
"country": {
"name": "Đức",
"cities": [
{
"name": "Berlin",
"population": 3.7,
"sightseeing": ["Cổng Brandenburg", "Reichstag"]
},
{
"name": "Munich",
"population": 1.5,
"sightseeing": ["Marienplatz", "Olympiapark"]
}
]
}
},
{
"id": 2,
"country": {
"name": "Nhật Bản",
"cities": [
{
"name": "Tokyo",
"population": 9.3,
"sightseeing": ["Tháp Tokyo", "Tokyo Skytree"]
},
{
"name": "Osaka",
"population": 2.7,
"sightseeing": ["Lâu đài Osaka", "Công viên Universal Studios Japan"]
}
]
}
}
]
Bạn có thể sử dụng dấu chấm để tìm kiếm các trường lồng nạp.
POST /collections/{tên_bộ_sưu_tập}/points/scroll
{
"filter": {
"should": [
{
"key": "country.name",
"match": {
"value": "Đức"
}
}
]
}
}
Bạn cũng có thể sử dụng cú pháp [ ]
để tìm kiếm trong mảng bằng cách trình bày các giá trị bên trong.
POST /collections/{tên_bộ_sưu_tập}/points/scroll
{
"filter": {
"should": [
{
"key": "country.cities[].population",
"range": {
"gte": 9.0,
}
}
]
}
}
Truy vấn này chỉ đầu ra điểm số có id 2, vì chỉ có Nhật Bản có một thành phố có dân số lớn hơn 9,0.
Các khóa lồng nạp cũng có thể là một mảng.
POST /collections/{tên_bộ_sưu_tập}/points/scroll
{
"filter": {
"should": [
{
"key": "country.cities[].sightseeing",
"match": {
"value": "Lâu đài Osaka"
}
}
]
}
}
Truy vấn này chỉ đầu ra điểm số có id 2, vì chỉ có Nhật Bản có một thành phố có điểm tham quan bao gồm "Lâu đài Osaka".
Lọc đối tượng lồng nhau
Có sẵn từ phiên bản 1.2.0
Mặc định, các điều kiện xem xét toàn bộ dữ liệu của một điểm.
Ví dụ, với hai điểm trong dữ liệu dưới đây:
[
{
"id": 1,
"dinosaur": "t-rex",
"diet": [
{ "food": "leaves", "likes": false},
{ "food": "meat", "likes": true}
]
},
{
"id": 2,
"dinosaur": "diplodocus",
"diet": [
{ "food": "leaves", "likes": true},
{ "food": "meat", "likes": false}
]
}
]
Truy vấn sau sẽ khớp với hai điểm này:
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{
"key": "diet[].food",
"match": {
"value": "meat"
}
},
{
"key": "diet[].likes",
"match": {
"value": true
}
}
]
}
}
Lý do các điểm trên khớp là vì cả hai điều này đều thỏa mãn hai điều kiện sau:
- "t-rex" thỏa mãn
diet[1].food
với food = meat vàdiet[1].likes
với likes = true - "diplodocus" thỏa mãn
diet[1].food
với food = meat vàdiet[0].likes
với likes = true
Để chỉ nhận các điểm khớp với các điều kiện cho các phần tử mảng, ví dụ: điểm với id 1 trong ví dụ này, bạn cần sử dụng bộ lọc đối tượng lồng nhau.
Bộ lọc đối tượng lồng nhau cho phép truy vấn mảng đối tượng một cách độc lập.
Điều này có thể được đạt được bằng cách sử dụng loại điều kiện nested
, bao gồm khóa dữ liệu quan tâm và bộ lọc để áp dụng.
Khóa nên trỏ đến một mảng đối tượng và có thể sử dụng notation dấu ngoặc vuông tùy chọn ("data" hoặc "data[]").
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{
"nested": {
"key": "diet",
"filter": {
"must": [
{
"key": "food",
"match": {
"value": "meat"
}
},
{
"key": "likes",
"match": {
"value": true
}
}
]
}
}
}
]
}
}
Logic khớp được sửa đổi để áp dụng ở mức phần tử mảng bên trong dữ liệu.
Bộ lọc lồng nhau hoạt động theo cách tương tự như khi áp dụng bộ lọc lồng nhau vào một phần tử duy nhất của một mảng. Miễn là ít nhất một phần tử của mảng khớp với bộ lọc lồng nhau, tài liệu cha được xem xét khớp với điều kiện.
Hạn chế
Bộ lọc đối tượng lồng nhau không hỗ trợ điều kiện has_id
. Nếu cần sử dụng nó, đặt nó trong mệnh đề must
kề cạnh.
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{
"nested": {
"key": "diet",
"filter": {
"must": [
{
"key": "food",
"match": {
"value": "meat"
}
},
{
"key": "likes",
"match": {
"value": true
}
}
]
}
}
},
{ "has_id": [1] }
]
}
}
Khớp Văn bản Chính xác
Có sẵn từ phiên bản 0.10.0
Một trường hợp đặc biệt của điều kiện match
là điều kiện khớp text
. Nó cho phép bạn tìm kiếm các chuỗi con, token hoặc cụm từ cụ thể trong trường văn bản.
Những văn bản chính xác thỏa mãn điều kiện này phụ thuộc vào cấu hình của chỉ mục văn bản đầy đủ. Cấu hình này được xác định khi chỉ mục được tạo và được mô tả trong chỉ mục văn bản đầy đủ.
Nếu trường không có chỉ mục văn bản đầy đủ, điều kiện này sẽ hoạt động dựa trên việc khớp chuỗi con chính xác.
{
"key": "description",
"match": {
"text": "tốt và rẻ"
}
}
Nếu truy vấn có nhiều từ, điều kiện này chỉ được xác nhận khi tất cả các từ xuất hiện trong văn bản.
Phạm vi
{
"key": "price",
"range": {
"gt": null,
"gte": 100.0,
"lt": null,
"lte": 450.0
}
}
Điều kiện range
đặt phạm vi giá trị có thể cho dữ liệu được lưu trữ. Nếu có nhiều giá trị được lưu trữ, ít nhất một giá trị phải khớp với điều kiện.
Các phép so sánh có sẵn bao gồm:
-
gt
- lớn hơn -
gte
- lớn hơn hoặc bằng -
lt
- nhỏ hơn -
lte
- nhỏ hơn hoặc bằng
Nó có thể được áp dụng cho số dấu phẩy động và dữ liệu số nguyên.
Hộp giới hạn địa lý
{
"key": "location",
"geo_bounding_box": {
"bottom_right": {
"lat": 52.495862,
"lon": 13.455868
},
"top_left": {
"lat": 52.520711,
"lon": 13.403683
}
}
}
Nó khớp với location
trong hình chữ nhật có tọa độ ở góc dưới bên phải là bottom_right
và tọa độ ở góc trên bên trái là top_left
.
Bán kính địa lý
{
"key": "location",
"geo_radius": {
"center": {
"lat": 52.520711,
"lon": 13.403683
},
"radius": 1000.0
}
}
Nó khớp với location
trong vòng tròn có tâm là center
và bán kính là radius
mét.
Nếu có nhiều giá trị được lưu trữ, ít nhất một giá trị phải khớp với điều kiện. Những điều kiện này chỉ có thể được áp dụng cho dữ liệu địa lý chính xác.
Số lượng giá trị
Ngoài việc so sánh trực tiếp giá trị, việc lọc cũng có thể dựa trên số lượng giá trị.
Ví dụ, với dữ liệu sau:
[
{ "id": 1, "name": "Sản phẩm A", "comments": ["Rất tốt!", "Xuất sắc"] },
{ "id": 2, "name": "Sản phẩm B", "comments": ["Công bằng", "Mong muốn thêm", "Tốt"] }
]
Chúng ta có thể tìm kiếm chỉ các mục có hơn hai nhận xét:
{
"key": "comments",
"values_count": {
"gt": 2
}
}
Kết quả sẽ là:
[{ "id": 2, "name": "Sản phẩm B", "comments": ["Công bằng", "Mong muốn thêm", "Tốt"] }]
Nếu giá trị lưu trữ không phải là mảng, ta giả định số lượng giá trị bằng 1.
Trống
Đôi khi, việc lọc ra các bản ghi thiếu một số giá trị cụ thể rất hữu ích. Điều kiện IsEmpty
có thể giúp bạn đạt được điều này:
{
"is_empty": {
"key": "reports"
}
}
Điều kiện này sẽ khớp với tất cả các bản ghi mà trường reports
không tồn tại hoặc có giá trị null
hoặc []
.
IsEmpty thường rất hữu ích khi sử dụng kết hợp với phủ định logic must_not. Trong trường hợp này, nó sẽ chọn tất cả các giá trị không trống.
Rỗng
Điều kiện match không thể kiểm tra giá trị NULL
. Chúng ta phải sử dụng điều kiện IsNull
:
{
"is_null": {
"key": "reports"
}
}
Điều kiện này sẽ khớp với tất cả các bản ghi mà trường reports
tồn tại và có giá trị NULL
.
Có ID
Loại truy vấn này không liên quan đến dữ liệu lưu trữ, nhưng nó rất hữu ích trong một số tình huống cụ thể. Ví dụ, người dùng có thể muốn đánh dấu kết quả tìm kiếm cụ thể là không liên quan, hoặc chúng ta có thể chỉ muốn tìm kiếm giữa các điểm cụ thể.
POST /collections/{collection_name}/points/scroll
{
"filter": {
"must": [
{ "has_id": [1,3,5,7,9,11] }
]
}
...
}
Các điểm lọc sẽ là:
[
{ "id": 1, "city": "London", "color": "xanh lá cây" },
{ "id": 3, "city": "London", "color": "xanh dương" },
{ "id": 5, "city": "Mát-xcơ-va", "color": "xanh lá cây" }
]