索引
如何索引和搜索 JSON 文档
除了索引 Redis 哈希之外,Redis 开源版还可以索引 JSON 文档。
使用 JSON 模式创建索引
当您使用 FT.CREATE
命令创建索引时,包含 ON JSON
关键字以索引数据库中任何现有和未来的 JSON 文档。
要定义 SCHEMA
,您可以提供 JSONPath 表达式。每个 JSONPath 表达式的结果都会被索引,并与一个称为 attribute
(以前称为 field
)的逻辑名称关联。您可以在查询中使用这些属性。
使用以下语法创建 JSON 索引
FT.CREATE {index_name} ON JSON SCHEMA {json_path} AS {attribute} {type}
例如,此命令创建一个索引,用于索引代表库存物品的每个 JSON 文档的名称、描述、价格和图像向量嵌入。
127.0.0.1:6379> FT.CREATE itemIdx ON JSON PREFIX 1 item: SCHEMA $.name AS name TEXT $.description as description TEXT $.price AS price NUMERIC $.embedding AS embedding VECTOR FLAT 6 DIM 4 DISTANCE_METRIC L2 TYPE FLOAT32
有关 JSON 索引 SCHEMA
限制的更多详细信息,请参阅索引限制。
添加 JSON 文档
创建索引后,Redis 会自动索引数据库中存储的任何现有、已修改或新创建的 JSON 文档。对于现有文档,索引会在后台异步运行,因此文档可用可能需要一些时间。已修改和新创建的文档会同步索引,因此文档将在添加或修改命令完成时立即可用。
您可以使用任何 JSON 写入命令,例如 JSON.SET
和 JSON.ARRAPPEND
,来创建或修改 JSON 文档。
以下示例使用这些 JSON 文档来表示单个库存物品。
物品 1 JSON 文档
{
"name": "Noise-cancelling Bluetooth headphones",
"description": "Wireless Bluetooth headphones with noise-cancelling technology",
"connection": {
"wireless": true,
"type": "Bluetooth"
},
"price": 99.98,
"stock": 25,
"colors": [
"black",
"silver"
],
"embedding": [0.87, -0.15, 0.55, 0.03]
}
物品 2 JSON 文档
{
"name": "Wireless earbuds",
"description": "Wireless Bluetooth in-ear headphones",
"connection": {
"wireless": true,
"type": "Bluetooth"
},
"price": 64.99,
"stock": 17,
"colors": [
"black",
"white"
],
"embedding": [-0.7, -0.51, 0.88, 0.14]
}
使用 JSON.SET
将这些文档存储在数据库中
127.0.0.1:6379> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"],"embedding":[0.87,-0.15,0.55,0.03]}'
"OK"
127.0.0.1:6379> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":64.99,"stock":17,"colors":["black","white"],"embedding":[-0.7,-0.51,0.88,0.14]}'
"OK"
由于此处的索引是同步的,因此文档将在 JSON.SET
命令返回后立即可在索引上访问。任何后续匹配索引内容的查询都将返回该文档。
搜索索引
要搜索索引中的 JSON 文档,请使用 FT.SEARCH
命令。您可以搜索 SCHEMA
中定义的任何属性。
例如,使用此查询搜索名称中包含“earbuds”一词的物品。
127.0.0.1:6379> FT.SEARCH itemIdx '@name:(earbuds)'
1) "1"
2) "item:2"
3) 1) "$"
2) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"connection\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"embedding\":[-0.7,-0.51,0.88,0.14]}"
此查询搜索描述中包含“bluetooth”和“headphones”的所有物品。
127.0.0.1:6379> FT.SEARCH itemIdx '@description:(bluetooth headphones)'
1) "2"
2) "item:1"
3) 1) "$"
2) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"], \"embedding\":[0.87,-0.15,0.55,0.03]}"
4) "item:2"
5) 1) "$"
2) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"connection\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"embedding\":[-0.7,-0.51,0.88,0.14]}"
现在搜索价格低于 70 的蓝牙耳机。
127.0.0.1:6379> FT.SEARCH itemIdx '@description:(bluetooth headphones) @price:[0 70]'
1) "1"
2) "item:2"
3) 1) "$"
2) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"connection\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"embedding\":[-0.7,-0.51,0.88,0.14]}"
最后,搜索与嵌入向量为 [1.0, 1.0, 1.0, 1.0] 的图像最相似的蓝牙耳机。
127.0.0.1:6379> FT.SEARCH itemIdx '@description:(bluetooth headphones)=>[KNN 2 @embedding $blob]' PARAMS 2 blob \x01\x01\x01\x01 DIALECT 2
1) "2"
2) "item:1"
3) 1) "__embedding_score"
2) "1.08280003071"
1) "$"
2) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"],\"embedding\":[0.87,-0.15,0.55,0.03]}"
2) "item:2"
3) 1) "__embedding_score"
2) "1.54409992695"
3) "$"
4) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"connection\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"embedding\":[-0.7,-0.51,0.88,0.14]}"
有关搜索查询的更多信息,请参阅搜索查询语法。
将 JSON 数组索引为 TAG
索引具有多值术语的 JSON 字段的首选方法是使用 JSON 数组。数组的每个值都会被索引,并且这些值必须是标量。如果您想将 JSON 数组中的字符串或布尔值索引为 TAG,请使用 JSONPath 通配符运算符。
要索引物品的可用颜色列表,请在索引创建期间的 SCHEMA
定义中指定 JSONPath $.colors.*
。
127.0.0.1:6379> FT.CREATE itemIdx2 ON JSON PREFIX 1 item: SCHEMA $.colors.* AS colors TAG $.name AS name TEXT $.description as description TEXT
现在您可以搜索银色耳机。
127.0.0.1:6379> FT.SEARCH itemIdx2 "@colors:{silver} (@name:(headphones)|@description:(headphones))"
1) "1"
2) "item:1"
3) 1) "$"
2) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"]}"
将 JSON 数组索引为 TEXT
从 RediSearch v2.6.0 开始,可以对字符串数组或指向多个字符串的 JSONPath 进行全文搜索。
如果您想将多个字符串值索引为 TEXT,请使用指向单个字符串数组的 JSONPath,或使用 JSONPath 运算符(如通配符、过滤器、联合、数组切片和/或递归下降)指向多个字符串值的 JSONPath。
要索引物品的可用颜色列表,请在索引创建期间的 SCHEMA
定义中指定 JSONPath $.colors
。
127.0.0.1:6379> FT.CREATE itemIdx3 ON JSON PREFIX 1 item: SCHEMA $.colors AS colors TEXT $.name AS name TEXT $.description as description TEXT
127.0.0.1:6379> JSON.SET item:3 $ '{"name":"True Wireless earbuds","description":"True Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":74.99,"stock":20,"colors":["red","light blue"]}'
"OK"
现在您可以对浅色耳机进行全文搜索。
127.0.0.1:6379> FT.SEARCH itemIdx3 '@colors:(white|light) (@name|description:(headphones))' RETURN 1 $.colors
1) (integer) 2
2) "item:2"
3) 1) "$.colors"
2) "[\"black\",\"white\"]"
4) "item:3"
5) 1) "$.colors"
2) "[\"red\",\"light blue\"]"
限制
-
当 JSONPath 可能指向多个值而不仅仅是一个数组时(例如,当 JSONPath 包含通配符等时),在
FT.SEARCH
中指定SLOP
或INORDER
将返回错误,因为匹配 JSONPath 的值的顺序不明确,可能导致结果不一致。例如,在如下所示的 JSON 值上使用诸如
$..b[*]
的 JSONPath 会发生什么。{ "a": [ {"b": ["first first", "first second"]}, {"c": {"b": ["second first", "second second"]}}, {"b": ["third first", "third second"]} ] }
可能会匹配各种顺序的值,具体取决于所使用的 JSONPath 库的具体实现。
由于
SLOP
和INORDER
会考虑索引值之间的相对顺序,并且结果在未来版本中可能会发生变化,因此将返回错误。 -
当 JSONPath 指向多个值时
- 字符串值被索引
null
值被跳过- 任何其他值类型都会导致索引失败
-
SORTBY
只按第一个值排序 -
不支持
HIGHLIGHT
和SUMMARIZE
-
RETURN
一个 JSONPath 指向多个值的 Schema 属性时,只返回第一个值(作为 JSON 字符串) -
如果
RETURN
指定的是 JSONPath 而不是 Schema 属性,则返回所有值(作为 JSON 字符串)
处理不同数组槽中的短语
索引时,使用预定义的增量来增加多个文本值在数组槽之间的位置偏移。此增量控制不同数组槽中短语之间的分隔级别(与 FT.SEARCH
的 SLOP
参数相关)。此预定义值由配置参数 MULTI_TEXT_SLOP
(在模块加载时)设置。默认值为 100。
将 JSON 数组索引为 NUMERIC
从 RediSearch v2.6.1 开始,可以对数值数组或指向多个数值的 JSONPath 进行搜索。
如果您想将多个数值索引为 NUMERIC,请使用指向单个数字数组的 JSONPath,或使用 JSONPath 运算符(如通配符、过滤器、联合、数组切片和/或递归下降)指向多个数字的 JSONPath。
例如,在物品列表中添加可用的音量 max_level
(以分贝为单位)。
127.0.0.1:6379> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"], "max_level":[60, 70, 80, 90, 100]}'
OK
127.0.0.1:6379> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":64.99,"stock":17,"colors":["black","white"], "max_level":[80, 100, 120]}'
OK
127.0.0.1:6379> JSON.SET item:3 $ '{"name":"True Wireless earbuds","description":"True Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":74.99,"stock":20,"colors":["red","light blue"], "max_level":[90, 100, 110, 120]}'
OK
要索引 max_level
数组,请在索引创建期间的 SCHEMA
定义中指定 JSONPath $.max_level
。
127.0.0.1:6379> FT.CREATE itemIdx4 ON JSON PREFIX 1 item: SCHEMA $.max_level AS dB NUMERIC
OK
现在您可以搜索具有特定最大音量的耳机,例如 70 到 80(包含)之间,返回其 max_level
数组中至少有一个值在请求范围内的物品。
127.0.0.1:6379> FT.SEARCH itemIdx4 '@dB:[70 80]'
1) (integer) 2
2) "item:1"
3) 1) "$"
2) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"],\"max_level\":[60,70,80,90,100]}"
4) "item:2"
5) 1) "$"
2) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"max_level\":[80,100,120]}"
您还可以搜索所有值都在特定范围内的物品。例如,所有值都在范围 [90, 120](包含)内。
127.0.0.1:6379> FT.SEARCH itemIdx4 '-@dB:[-inf (90] -@dB:[(120 +inf]'
1) (integer) 1
2) "item:3"
3) 1) "$"
2) "{\"name\":\"True Wireless earbuds\",\"description\":\"True Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":74.99,\"stock\":20,\"colors\":[\"red\",\"light blue\"],\"max_level\":[90,100,110,120]}"
限制
当 JSONPath 指向多个数值时
- 数值被索引
null
值被跳过- 任何其他值类型都会导致索引失败
将 JSON 数组索引为 GEO 和 GEOSHAPE
您可以使用 GEO
和 GEOSHAPE
字段存储地理空间数据,例如地理位置和几何形状。请参阅地理空间索引了解如何使用这些模式类型,并参阅地理空间参考页面了解其格式和用法简介。
将 JSON 数组索引为 VECTOR
从 RediSearch 2.6.0 开始,您可以在索引模式中将指向数值数组的 JSONPath 索引为 VECTOR 类型。
例如,假设您的 JSON 物品包含一个向量嵌入数组,其中每个向量代表产品的图像。要索引这些向量,请在索引创建期间的模式定义中指定 JSONPath $.embedding
。
127.0.0.1:6379> FT.CREATE itemIdx5 ON JSON PREFIX 1 item: SCHEMA $.embedding AS embedding VECTOR FLAT 6 DIM 4 DISTANCE_METRIC L2 TYPE FLOAT32
OK
127.0.0.1:6379> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","price":99.98,"stock":25,"colors":["black","silver"],"embedding":[0.87,-0.15,0.55,0.03]}'
OK
127.0.0.1:6379> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","price":64.99,"stock":17,"colors":["black","white"],"embedding":[-0.7,-0.51,0.88,0.14]}'
OK
现在您可以使用向量搜索 KNN 查询搜索与图像嵌入最相似的两个耳机。(注意,向量查询自方言 2 起受支持。)例如
127.0.0.1:6379> FT.SEARCH itemIdx5 '*=>[KNN 2 @embedding $blob AS dist]' SORTBY dist PARAMS 2 blob \x01\x01\x01\x01 DIALECT 2
1) (integer) 2
2) "item:1"
3) 1) "dist"
2) "1.08280003071"
3) "$"
4) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"],\"embedding\":[0.87,-0.15,0.55,0.03]}"
4) "item:2"
5) 1) "dist"
2) "1.54409992695"
3) "$"
4) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"embedding\":[-0.7,-0.51,0.88,0.14]}"
如果您想将多个数值数组索引为 VECTOR,请使用 JSONPath,通过使用 JSONPath 运算符(如通配符、过滤器、联合、数组切片和/或递归下降)指向多个数值数组。
例如,假设您的 JSON 物品包含一个向量嵌入数组,其中每个向量代表同一产品的不同图像。要索引这些向量,请在索引创建期间的模式定义中指定 JSONPath $.embeddings[*]
。
127.0.0.1:6379> FT.CREATE itemIdx5 ON JSON PREFIX 1 item: SCHEMA $.embeddings[*] AS embeddings VECTOR FLAT 6 DIM 4 DISTANCE_METRIC L2 TYPE FLOAT32
OK
127.0.0.1:6379> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","price":99.98,"stock":25,"colors":["black","silver"],"embeddings":[[0.87,-0.15,0.55,0.03]]}'
OK
127.0.0.1:6379> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","price":64.99,"stock":17,"colors":["black","white"],"embeddings":[[-0.7,-0.51,0.88,0.14],[-0.8,-0.15,0.33,-0.01]]}'
OK
$.embedding
)不允许您索引存储在该字段下的多个向量。因此,如果您将 $.embedding
设置为索引模式的路径,在 JSON 的 embedding
字段中指定向量数组将导致索引失败。现在您可以使用向量搜索 KNN 查询搜索与图像嵌入最相似的两个耳机。(注意,向量查询自方言 2 起受支持。)文档到查询向量的距离定义为查询向量与模式中指定的 JSONPath 匹配的向量之间的最小距离。例如
127.0.0.1:6379> FT.SEARCH itemIdx5 '*=>[KNN 2 @embeddings $blob AS dist]' SORTBY dist PARAMS 2 blob \x01\x01\x01\x01 DIALECT 2
1) (integer) 2
2) "item:2"
3) 1) "dist"
2) "0.771500051022"
3) "$"
4) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"embeddings\":[[-0.7,-0.51,0.88,0.14],[-0.8,-0.15,0.33,-0.01]]}"
4) "item:1"
5) 1) "dist"
2) "1.08280003071"
3) "$"
4) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"],\"embeddings\":[[0.87,-0.15,0.55,0.03]]}"
请注意,0.771500051022
是查询向量与 [-0.8,-0.15,0.33,-0.01]
(即嵌入数组中的第二个元素)之间的 L2 距离,并且它低于查询向量与 [-0.7,-0.51,0.88,0.14]
(即嵌入数组中的第一个元素)之间的 L2 距离。
有关向量相似性语法的更多信息,请参阅向量字段。
索引 JSON 对象
您不能索引 JSON 对象。如果 JSONPath 表达式返回一个对象,它将被忽略。
要索引 JSON 对象的内容,您需要将对象内的各个元素在单独的属性中进行索引。
例如,要索引 connection
JSON 对象,请在创建索引时将 $.connection.wireless
和 $.connection.type
字段定义为单独的属性。
127.0.0.1:6379> FT.CREATE itemIdx3 ON JSON SCHEMA $.connection.wireless AS wireless TAG $.connection.type AS connectionType TEXT
"OK"
创建新索引后,您可以搜索 wireless TAG 设置为 true
的物品。
127.0.0.1:6379> FT.SEARCH itemIdx3 '@wireless:{true}'
1) "2"
2) "item:2"
3) 1) "$"
2) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"connection\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"]}"
4) "item:1"
5) 1) "$"
2) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"]}"
您也可以搜索连接类型为 Bluetooth 的物品。
127.0.0.1:6379> FT.SEARCH itemIdx3 '@connectionType:(bluetooth)'
1) "2"
2) "item:1"
3) 1) "$"
2) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"]}"
4) "item:2"
5) 1) "$"
2) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"]}"
字段投影
FT.SEARCH
默认返回整个 JSON 文档。如果您想将返回的搜索结果限制为特定属性,可以使用字段投影。
返回特定属性
运行搜索查询时,可以使用 RETURN
关键字指定要在搜索结果中包含的属性。您还需要指定要返回的字段数。
例如,此查询只返回每套耳机的 name
和 price
。
127.0.0.1:6379> FT.SEARCH itemIdx '@description:(headphones)' RETURN 2 name price
1) "2"
2) "item:1"
3) 1) "name"
2) "Noise-cancelling Bluetooth headphones"
3) "price"
4) "99.98"
4) "item:2"
5) 1) "name"
2) "Wireless earbuds"
3) "price"
4) "64.99"
使用 JSONPath 进行投影
您可以在 RETURN
语句中使用 JSONPath 表达式提取 JSON 文档的任何部分,即使是未在索引 SCHEMA
中定义的字段也可以。
例如,以下查询使用 JSONPath 表达式 $.stock
返回每个物品的库存,以及名称和价格属性。
127.0.0.1:6379> FT.SEARCH itemIdx '@description:(headphones)' RETURN 3 name price $.stock
1) "2"
2) "item:1"
3) 1) "name"
2) "Noise-cancelling Bluetooth headphones"
3) "price"
4) "99.98"
5) "$.stock"
6) "25"
4) "item:2"
5) 1) "name"
2) "Wireless earbuds"
3) "price"
4) "64.99"
5) "$.stock"
6) "17"
注意,返回的属性名称是 JSONPath 表达式本身:"$.stock"
。
您可以使用 AS
选项为返回的属性指定别名。
127.0.0.1:6379> FT.SEARCH itemIdx '@description:(headphones)' RETURN 5 name price $.stock AS stock
1) "2"
2) "item:1"
3) 1) "name"
2) "Noise-cancelling Bluetooth headphones"
3) "price"
4) "99.98"
5) "stock"
6) "25"
4) "item:2"
5) 1) "name"
2) "Wireless earbuds"
3) "price"
4) "64.99"
5) "stock"
6) "17"
此查询将字段作为别名 "stock"
返回,而不是 JSONPath 表达式 "$.stock"
。
突出显示搜索词
您可以在任何已索引的 TEXT
属性中突出显示相关的搜索词。
对于 FT.SEARCH
,您需要在 RETURN
和 HIGHLIGHT
参数之后明确设置要突出显示的属性。
使用可选的 TAGS
关键字指定用于环绕(或突出显示)匹配搜索词的字符串。
例如,在物品名称和描述中使用粗体 HTML 标签突出显示“bluetooth”一词。
127.0.0.1:6379> FT.SEARCH itemIdx '(@name:(bluetooth))|(@description:(bluetooth))' RETURN 3 name description price HIGHLIGHT FIELDS 2 name description TAGS '<b>' '</b>'
1) "2"
2) "item:1"
3) 1) "name"
2) "Noise-cancelling <b>Bluetooth</b> headphones"
3) "description"
4) "Wireless <b>Bluetooth</b> headphones with noise-cancelling technology"
5) "price"
6) "99.98"
4) "item:2"
5) 1) "name"
2) "Wireless earbuds"
3) "description"
4) "Wireless <b>Bluetooth</b> in-ear headphones"
5) "price"
6) "64.99"
使用 JSONPath 进行聚合
您可以使用聚合来生成统计信息或构建分面查询。
LOAD
选项接受 JSONPath 表达式。您可以在管道中使用任何值,即使该值未被索引。
此示例使用聚合计算每个物品的 10% 价格折扣,并按价格从低到高对物品进行排序。
127.0.0.1:6379> FT.AGGREGATE itemIdx '*' LOAD 4 name $.price AS originalPrice APPLY '@originalPrice - (@originalPrice * 0.10)' AS salePrice SORTBY 2 @salePrice ASC
1) "2"
2) 1) "name"
2) "Wireless earbuds"
3) "originalPrice"
4) "64.99"
5) "salePrice"
6) "58.491"
3) 1) "name"
2) "Noise-cancelling Bluetooth headphones"
3) "originalPrice"
4) "99.98"
5) "salePrice"
6) "89.982"
索引缺失或空值
从 v2.10 开始,您可以使用 FT.CREATE
的 INDEXMISSING
选项以及 FT.SEARCH
的 ismissing
查询函数来搜索缺失的属性,即给定文档中不存在的属性。您还可以使用 FT.CREATE
的 INDEXEMPTY
选项搜索没有值(即空)的现有属性。这两种查询类型都需要 DIALECT 2。示例如下
JSON.SET key:1 $ '{"propA": "foo"}'
JSON.SET key:2 $ '{"propA": "bar", "propB":"abc"}'
FT.CREATE idx ON JSON PREFIX 1 key: SCHEMA $.propA AS propA TAG $.propB AS propB TAG INDEXMISSING
> FT.SEARCH idx 'ismissing(@propB)' DIALECT 2
1) "1"
2) "key:1"
3) 1) "$"
2) "{\"propA\":\"foo\"}"
JSON.SET key:1 $ '{"propA": "foo", "propB":""}'
JSON.SET key:2 $ '{"propA": "bar", "propB":"abc"}'
FT.CREATE idx ON JSON PREFIX 1 key: SCHEMA $.propA AS propA TAG $.propB AS propB TAG INDEXEMPTY
> FT.SEARCH idx '@propB:{""}' DIALECT 2
1) "1"
2) "key:1"
3) 1) "$"
2) "{\"propA\":\"foo\",\"propB\":\"\"}"
索引限制
模式映射
在索引创建期间,您需要按如下方式将 JSON 元素映射到 SCHEMA
字段:
- 字符串作为
TEXT
、TAG
或GEO
。 - 数字作为
NUMERIC
。 - 布尔值作为
TAG
。 - JSON 数组
- 字符串数组作为
TAG
或TEXT
。 - 数字数组作为
NUMERIC
或VECTOR
。 - 地理坐标数组作为
GEO
。 - 此类数组中的
null
值将被忽略。
- 字符串数组作为
- 您不能索引 JSON 对象。请改为将各个元素作为单独的属性进行索引。
null
值将被忽略。
可排序标签
如果您为 JSON 文档创建索引,并且 JSONPath 指向数组或多个值,则排序时只考虑第一个值。