数据管理
qdrant中的数据以点为基本单位,每个点都包含向量和payload
向量:
- 定义了数据如何在向量空间中表示
- 支持密集,稀疏和多向量
负载: 可以附加到点的结构化元数据,支持过滤
集合: 点的集合
相似性搜索
搜索nearest vectors 是许多representation learning应用的核心。神经网络经过训练之后,可以将对象转化为向量,使现实中相近的对象,在向量空间也表现为相互接近
这些对象可以是含义相似的文本,视觉相似的图片,或相似的音乐
查询API
qdrant的查询方法包括最邻近搜索,按id搜索等

评估向量相似度的方法主要有以下几种:
点积, 余弦相似度, 欧几里得距离, 曼哈顿距离
相似度学习模型中最常用的度量是余弦度量。

Qdrant 分两步计算此度量,从而实现更高的搜索速度。第一步是在将向量添加到集合时对其进行归一化。每个向量只需执行一次此操作
第二步是比较向量 。在这种情况下,它变得等同于点积------由于 SIMD 的使用,这是一项非常快的操作。
筛选
使用 Qdrant 时,您可以在搜索或检索点时设置条件。例如,您可以对 payload(有效载荷)和点的 id 施加条件。
过滤子句
Qdrant 允许您在子句中组合条件。子句是不同的逻辑运算,例如 OR、AND 和 NOT。子句可以递归嵌套,以便您可以重现任意布尔表达式
让我们看看 Qdrant 中实现的子句。
假设我们有一组具有以下 payload 的点
MUST
使用must时,只有当must内部列出的每个条件都满足时,子句才为true。所以MUST = AND
python
from qdrant_client import QdrantClient, models
client = QdrantClient(url="https://:6333")
client.scroll(
collection_name="{collection_name}",
scroll_filter=models.Filter(
must=[
models.FieldCondition(
key="city",
match=models.MatchValue(value="London"),
),
models.FieldCondition(
key="color",
match=models.MatchValue(value="red"),
),
]
),
)
过滤后的点将是
css
[{ "id": 2, "city": "London", "color": "red" }]
即city为London同时color为red
SHOULD
使用 should 时,如果至少满足 should 内部列出的一个条件,则子句为 true 。从这个意义上说,should 等同于 OR 运算符。
python
client.scroll(
collection_name="{collection_name}",
scroll_filter=models.Filter(
should=[
models.FieldCondition(
key="city",
match=models.MatchValue(value="London"),
),
models.FieldCondition(
key="color",
match=models.MatchValue(value="red"),
),
]
),
)
过滤后的点:
css
[ { "id": 1, "city": "London", "color": "green" }, { "id": 2, "city": "London", "color": "red" }, { "id": 3, "city": "London", "color": "blue" }, { "id": 4, "city": "Berlin", "color": "red" }]
也就是city为London或者color为red的都算
Must Not
使用 must_not 时,如果 must_not 内部列出的条件均未满足,则子句为 true。从这个意义上说,must_not 等同于表达式 (NOT A) AND (NOT B) AND (NOT C)。
python
client.scroll(
collection_name="{collection_name}",
scroll_filter=models.Filter(
must_not=[
models.FieldCondition(key="city", match=models.MatchValue(value="London")),
models.FieldCondition(key="color", match=models.MatchValue(value="red")),
]
),
)
过滤后的点:
css
[ { "id": 5, "city": "Moscow", "color": "green" }, { "id": 6, "city": "Moscow", "color": "blue" }]
子句组合
也可以同时使用多个子句
python
client.scroll(
collection_name="{collection_name}",
scroll_filter=models.Filter(
must=[
models.FieldCondition(key="city", match=models.MatchValue(value="London")),
],
must_not=[
models.FieldCondition(key="color", match=models.MatchValue(value="red")),
],
),
)
过滤后的点为:
css
[ { "id": 1, "city": "London", "color": "green" }, { "id": 3, "city": "London", "color": "blue" }]
在这种情况下,条件通过 AND 组合。 也就是city为London,且color不是red
此外,条件可以递归嵌套。示例:
ini
client.scroll(
collection_name="{collection_name}",
scroll_filter=models.Filter(
must_not=[
models.Filter(
must=[
models.FieldCondition(
key="city", match=models.MatchValue(value="London")
),
models.FieldCondition(
key="color", match=models.MatchValue(value="red")
),
],
),
],
),
)
在MustNOT中嵌入了一个子查询,即查询出的结果不能为city为London且color为red的
过滤条件
匹配(MATCH)
python
models.FieldCondition(
key="color",
match=models.MatchValue(value="red"),
)
python
models.FieldCondition(
key="count",
match=models.MatchValue(value=0),
)
匹配任意 (Match Any)
如果您想检查存储的值是否为多个值之一,可以使用 Match Any(匹配任意)条件。Match Any 作用于给定值的逻辑 OR。它也可以描述为 IN 运算符。
您可以将其应用于 keyword 和 integer 类型的 payload。
python
models.FieldCondition(
key="color",
match=models.MatchAny(any=["black", "yellow"]),
)
在此示例中,如果存储的值为black或者yellow,则条件满足
如果存储的值是一个数组,它应该至少有一个值匹配给定的任何值。例如,如果存储的值是 ["black", "green"],则条件将满足,因为 "black" 在 ["black", "yellow"] 中。
匹配排除 (Match Except)
如果您想检查存储的值是否不是多个值之一,可以使用 Match Except(匹配排除)条件。Match Except 作用于给定值的逻辑 NOR。它也可以描述为 NOT IN 运算符。
python
models.FieldCondition(
key="color",
match=models.MatchExcept(**{"except": ["black", "yellow"]}),
)
在此示例中,如果存储的值既不是 black 也不是 yellow,则条件满足。
如果存储的值是一个数组,它应该至少有一个值不匹配给定的任何值。例如,如果存储的值是 ["black", "green"],则条件将满足,因为 "green" 既不匹配 "black" 也不匹配 "yellow"。
嵌套键
由于 payload 是任意 JSON 对象,因此您很可能需要对嵌套字段进行过滤。
假设我们有一组具有以下 payload 的点
python
[
{
"id": 1,
"country": {
"name": "Germany",
"cities": [
{
"name": "Berlin",
"population": 3.7,
"sightseeing": ["Brandenburg Gate", "Reichstag"]
},
{
"name": "Munich",
"population": 1.5,
"sightseeing": ["Marienplatz", "Olympiapark"]
}
]
}
},
{
"id": 2,
"country": {
"name": "Japan",
"cities": [
{
"name": "Tokyo",
"population": 9.3,
"sightseeing": ["Tokyo Tower", "Tokyo Skytree"]
},
{
"name": "Osaka",
"population": 2.7,
"sightseeing": ["Osaka Castle", "Universal Studios Japan"]
}
]
}
}
]
python
client.scroll(
collection_name="{collection_name}",
scroll_filter=models.Filter(
should=[
models.FieldCondition(
key="country.name", match=models.MatchValue(value="Germany")
),
],
),
)