查询和过滤
使用 RedisVL 查询和过滤
在本文件中,您将探索使用 RedisVL 可以执行的更复杂的查询。
在开始之前,请确保以下事项
- 您已安装 RedisVL 并且该环境已激活。
- 您有一个运行中的 Redis 实例,具有搜索和查询功能。
示例二进制数据位于 GitHub 上的此文件 中。
import pickle
from jupyterutils import table_print, result_print
# load in the example data and printing utils
data = pickle.load(open("hybrid_example_data.pkl", "rb"))
table_print(data)
用户 | 年龄 | 工作 | 信用评分 | 办公地点 | 用户嵌入 |
---|
约翰 | 18 | 工程师 | 高 | -122.4194,37.7749 | b'\xcd\xcc\xcc=\xcd\xcc\xcc=\x00\x00\x00?' |
德里克 | 14 | 医生 | 低 | -122.4194,37.7749 | b'\xcd\xcc\xcc=\xcd\xcc\xcc=\x00\x00\x00?' |
南希 | 94 | 医生 | 高 | -122.4194,37.7749 | b'333?\xcd\xcc\xcc=\x00\x00\x00?' |
泰勒 | 100 | 工程师 | 高 | -122.0839,37.3861 | b'\xcd\xcc\xcc=\xcd\xcc\xcc>\x00\x00\x00?' |
蒂姆 | 12 | 皮肤科医生 | 高 | -122.0839,37.3861 | b'\xcd\xcc\xcc>\xcd\xcc\xcc>\x00\x00\x00?' |
泰穆尔 | 15 | 首席执行官 | 低 | -122.0839,37.3861 | b'\x9a\x99\x19?\xcd\xcc\xcc=\x00\x00\x00?' |
乔 | 35 | 牙医 | 中等 | -122.0839,37.3861 | b'fff?fff?\xcd\xcc\xcc=' |
schema = {
"index": {
"name": "user_queries",
"prefix": "user_queries_docs",
"storage_type": "hash", # default setting -- HASH
},
"fields": [
{"name": "user", "type": "tag"},
{"name": "credit_score", "type": "tag"},
{"name": "job", "type": "text"},
{"name": "age", "type": "numeric"},
{"name": "office_location", "type": "geo"},
{
"name": "user_embedding",
"type": "vector",
"attrs": {
"dims": 3,
"distance_metric": "cosine",
"algorithm": "flat",
"datatype": "float32"
}
}
],
}
from redisvl.index import SearchIndex
# construct a search index from the schema
index = SearchIndex.from_dict(schema)
# connect to local redis instance
index.connect("redis://localhost:6379")
# create the index (no data yet)
index.create(overwrite=True)
# inspect the newly-created index
$ rvl index listall
18:26:34 [RedisVL] INFO Indices:
18:26:34 [RedisVL] INFO 1. user_queries
混合查询
混合查询是将多种类型的过滤器组合在一起的查询。例如,您可能想要搜索一个特定年龄、特定工作并且距离某个位置一定距离的用户。这是一种混合查询,它结合了数字、标签和地理过滤器。
标签过滤器
标签过滤器是应用于标签字段的过滤器。这些字段没有被分词,用于存储单个分类值。
from redisvl.query import VectorQuery
from redisvl.query.filter import Tag
t = Tag("credit_score") == "high"
v = VectorQuery([0.1, 0.1, 0.5],
"user_embedding",
return_fields=["user", "credit_score", "age", "job", "office_location"],
filter_expression=t)
results = index.query(v)
result_print(results)
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
# negation
t = Tag("credit_score") != "high"
v.set_filter(t)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
# use multiple tags as a list
t = Tag("credit_score") == ["high", "medium"]
v.set_filter(t)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
# use multiple tags as a set (to enforce uniqueness)
t = Tag("credit_score") == set(["high", "high", "medium"])
v.set_filter(t)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
如果要动态生成标签列表,该怎么办?RedisVL 允许您优雅地完成此操作,而无需检查空情况。空情况是指在没有定义的值与之匹配的字段上尝试运行标签过滤器时。例如
Tag("credit_score") == []
上面这样的空过滤器将产生一个 *
Redis 查询过滤器,它表示基本情况:没有过滤器。
# gracefully fallback to "*" filter if empty case
empty_case = Tag("credit_score") == []
v.set_filter(empty_case)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
数字过滤器
数字过滤器是应用于数字字段的过滤器,可用于隔离给定字段的某个值范围。
from redisvl.query.filter import Num
numeric_filter = Num("age") > 15
v.set_filter(numeric_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
# exact match query
numeric_filter = Num("age") == 14
v.set_filter(numeric_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
# negation
numeric_filter = Num("age") != 14
v.set_filter(numeric_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
文本过滤器
文本过滤器是应用于文本字段的过滤器。这些过滤器应用于整个文本字段。例如,如果您有一个包含文本“The quick brown fox jumps over the lazy dog”的文本字段,则文本过滤器“quick”将匹配此文本字段。
from redisvl.query.filter import Text
# exact match filter -- document must contain the exact word doctor
text_filter = Text("job") == "doctor"
v.set_filter(text_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
# negation -- document must not contain the exact word doctor
negate_text_filter = Text("job") != "doctor"
v.set_filter(negate_text_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
# wildcard match filter
wildcard_filter = Text("job") % "doct*"
v.set_filter(wildcard_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
# fuzzy match filter
fuzzy_match = Text("job") % "%%engine%%"
v.set_filter(fuzzy_match)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
# conditional -- match documents with job field containing engineer OR doctor
conditional = Text("job") % "engineer|doctor"
v.set_filter(conditional)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
# gracefully fallback to "*" filter if empty case
empty_case = Text("job") % ""
v.set_filter(empty_case)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
地理过滤器
地理过滤器是应用于地理字段的过滤器。这些过滤器用于查找距离给定点一定距离的结果。距离以公里、英里、米或英尺指定。还可以指定一个半径,以查找距离给定点一定半径内的结果。
from redisvl.query.filter import Geo, GeoRadius
# within 10 km of San Francisco office
geo_filter = Geo("office_location") == GeoRadius(-122.4194, 37.7749, 10, "km")
v.set_filter(geo_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
# within 100 km Radius of San Francisco office
geo_filter = Geo("office_location") == GeoRadius(-122.4194, 37.7749, 100, "km")
v.set_filter(geo_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
# not within 10 km Radius of San Francisco office
geo_filter = Geo("office_location") != GeoRadius(-122.4194, 37.7749, 10, "km")
v.set_filter(geo_filter)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
组合过滤器
在本例中,您将结合数字过滤器和标签过滤器,并搜索年龄在 20 到 30 岁之间且职位为“工程师”的用户。
交集 (“and”)
t = Tag("credit_score") == "high"
low = Num("age") >= 18
high = Num("age") <= 100
combined = t & low & high
v = VectorQuery([0.1, 0.1, 0.5],
"user_embedding",
return_fields=["user", "credit_score", "age", "job", "office_location"],
filter_expression=combined)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
并集 (“or”)
两个查询的并集是两个查询返回的所有结果的集合。两个查询的并集使用 |
运算符执行。
low = Num("age") < 18
high = Num("age") > 93
combined = low | high
v.set_filter(combined)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
动态组合
通常,您可能希望在给定查询中使用或不使用过滤器。如上所示,过滤器将接受 None
类型并恢复到通配符过滤器,该过滤器返回所有结果。
过滤器组合也是如此,它使您能够快速重复使用过滤器,并在具有不同参数的请求中使用,如下所示。这样就不需要使用许多“if-then”条件来测试空情况。
def make_filter(age=None, credit=None, job=None):
flexible_filter = (
(Num("age") > age) &
(Tag("credit_score") == credit) &
(Text("job") % job)
)
return flexible_filter
# all parameters
combined = make_filter(age=18, credit="high", job="engineer")
v.set_filter(combined)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
# just age and credit_score
combined = make_filter(age=18, credit="high")
v.set_filter(combined)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
# just age
combined = make_filter(age=18)
v.set_filter(combined)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
# no filters
combined = make_filter()
v.set_filter(combined)
result_print(index.query(v))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 | 办公地点 |
---|
0 | 约翰 | 高 | 18 | 工程师 | -122.4194,37.7749 |
0 | 德里克 | 低 | 14 | 医生 | -122.4194,37.7749 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 | -122.0839,37.3861 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 | -122.0839,37.3861 |
0.217882037163 | 泰穆尔 | 低 | 15 | 首席执行官 | -122.0839,37.3861 |
0.266666650772 | 南希 | 高 | 94 | 医生 | -122.4194,37.7749 |
0.653301358223 | 乔 | 中等 | 35 | 牙医 | -122.0839,37.3861 |
过滤器查询
在某些情况下,您可能不想运行向量查询,而只想使用类似 SQL 查询的 FilterExpression
。FilterQuery
类支持此功能。它类似于 VectorQuery
类,但仅接受 FilterExpression
。
from redisvl.query import FilterQuery
has_low_credit = Tag("credit_score") == "low"
filter_query = FilterQuery(
return_fields=["user", "credit_score", "age", "job", "location"],
filter_expression=has_low_credit
)
results = index.query(filter_query)
result_print(results)
用户 | 信用评分 | 年龄 | 工作 |
---|
德里克 | 低 | 14 | 医生 |
泰穆尔 | 低 | 15 | 首席执行官 |
计数查询
在某些情况下,您可能需要使用 FilterExpression
来执行 CountQuery
,它只返回相关集中实体的数量。它类似于 FilterQuery
类,但不返回基础数据的价值。
from redisvl.query import CountQuery
has_low_credit = Tag("credit_score") == "low"
filter_query = CountQuery(filter_expression=has_low_credit)
count = index.query(filter_query)
print(f"{count} records match the filter expression {str(has_low_credit)} for the given index.")
2 records match the filter expression @credit_score:{low} for the given index.
范围查询
范围查询对于执行向量搜索非常有用,其中只返回向量 distance_threshold
内的结果。这使用户能够查找其数据集中与查询向量相似的所有记录,其中“相似”由一个定量值定义。
from redisvl.query import RangeQuery
range_query = RangeQuery(
vector=[0.1, 0.1, 0.5],
vector_field_name="user_embedding",
return_fields=["user", "credit_score", "age", "job", "location"],
distance_threshold=0.2
)
# same as the vector query or filter query
results = index.query(range_query)
result_print(results)
向量距离 | 用户 | 信用评分 | 年龄 | 工作 |
---|
0 | 约翰 | 高 | 18 | 工程师 |
0 | 德里克 | 低 | 14 | 医生 |
0.109129190445 | 泰勒 | 高 | 100 | 工程师 |
0.158808946609 | 蒂姆 | 高 | 12 | 皮肤科医生 |
您还可以在不同使用之间更改查询对象的距离阈值。这里,您将设置 distance_threshold==0.1
。这意味着查询对象将返回所有与查询对象相距 0.1 以内的匹配项。这是一个很小的距离,所以预计获得的匹配项将少于以前。
range_query.set_distance_threshold(0.1)
result_print(index.query(range_query))
向量距离 | 用户 | 信用评分 | 年龄 | 工作 |
---|
0 | 约翰 | 高 | 18 | 工程师 |
0 | 德里克 | 低 | 14 | 医生 |
范围查询也可以与其他任何类型的查询一起使用过滤器。以下示例将结果限制为只有那些 job
为 engineer
且位于向量范围(即距离)内的记录。
is_engineer = Text("job") == "engineer"
range_query.set_filter(is_engineer)
result_print(index.query(range_query))
其他 Redis 查询
在某些情况下,RedisVL 可能无法涵盖查询所需的显式功能,要么是因为客户端尚未实现新版本,要么是因为使用案例非常特殊。在这种情况下,可以使用 SearchIndex.search
方法使用 redis-py Query
对象或通过原始 Redis 字符串执行查询。
redis-py
# Manipulate the redis-py Query object
redis_py_query = v.query
# choose to sort by age instead of vector distance
redis_py_query.sort_by("age", asc=False)
# run the query with the ``SearchIndex.search`` method
result = index.search(redis_py_query, v.params)
result_print(result)
向量距离 | 年龄 | 用户 | 信用评分 | 工作 | 办公地点 |
---|
0.109129190445 | 100 | 泰勒 | 高 | 工程师 | -122.0839,37.3861 |
0.266666650772 | 94 | 南希 | 高 | 医生 | -122.4194,37.7749 |
0.653301358223 | 35 | 乔 | 中等 | 牙医 | -122.0839,37.3861 |
0 | 18 | 约翰 | 高 | 工程师 | -122.4194,37.7749 |
0.217882037163 | 15 | 泰穆尔 | 低 | 首席执行官 | -122.0839,37.3861 |
0 | 14 | 德里克 | 低 | 医生 | -122.4194,37.7749 |
0.158808946609 | 12 | 蒂姆 | 高 | 皮肤科医生 | -122.0839,37.3861 |
原始 Redis 查询字符串
一种情况可能是您想要进行仅在标签字段上进行过滤的搜索,而不需要其他功能。相反,您可能需要比目前 RedisVL 支持的更复杂的查询。在这种情况下,可以使用 SearchIndex.search
方法,并使用原始 Redis 查询字符串。
t = Tag("credit_score") == "high"
str(t)
'@credit_score:{high}'
results = index.search(str(t))
for r in results.docs:
print(r.__dict__)
{'id': 'user_queries_docs:0e511391dcf346639669bdba70a189c0', 'payload': None, 'user': 'john', 'age': '18', 'job': 'engineer', 'credit_score': 'high', 'office_location': '-122.4194,37.7749', 'user_embedding': '==\x00\x00\x00?'}
{'id': 'user_queries_docs:d204e8e5df90467dbff5b2fb6f800a78', 'payload': None, 'user': 'nancy', 'age': '94', 'job': 'doctor', 'credit_score': 'high', 'office_location': '-122.4194,37.7749', 'user_embedding': '333?=\x00\x00\x00?'}
{'id': 'user_queries_docs:7cf3d6b1a4044966b4f0c5d3725a5e03', 'payload': None, 'user': 'tyler', 'age': '100', 'job': 'engineer', 'credit_score': 'high', 'office_location': '-122.0839,37.3861', 'user_embedding': '=>\x00\x00\x00?'}
{'id': 'user_queries_docs:f6581edaaeaf432a85c1d1df8fdf5edc', 'payload': None, 'user': 'tim', 'age': '12', 'job': 'dermatologist', 'credit_score': 'high', 'office_location': '-122.0839,37.3861', 'user_embedding': '>>\x00\x00\x00?'}
检查查询
在本例中,您将学习如何检查由 RedisVL 生成的查询。这对于调试目的或了解查询的执行方式非常有用。
考虑一个结合数字过滤器和标签过滤器的查询示例。这将搜索年龄在 18 到 100 岁之间、信用评分高且按与查询向量的最近向量距离排序的结果。
t = Tag("credit_score") == "high"
low = Num("age") >= 18
high = Num("age") <= 100
combined = t & low & high
v.set_filter(combined)
# Using the str() method, you can see what Redis Query this will emit.
str(v)
'((@credit_score:{high} @age:[18 +inf]) @age:[-inf 100])=>[KNN 10 @user_embedding $vector AS vector_distance] RETURN 6 user credit_score age job office_location vector_distance SORTBY vector_distance ASC DIALECT 2 LIMIT 0 10'