结合动态字段和 N1QL 的 Couchbase 全文搜索
Couchbase Full Text search with combination of dynamic fields and N1QL
考虑以下文档并考虑在以下文档上创建全文索引:
{
email : "A",
"data" : {
"dynamic_property" : "ANY_TYPE",
"dynamic_property2" : {
"property" : "searchableValue"
},
"field" : "VALUE"
}
},
{
email : "B",
"data" : {
"other_dynamic_prop" : "test-searchableValue-2",
}
},
{
email : "A",
"data" : {
"thirdDynamicProp" : {
"childProp" : "this should be searchableValue!"
}
}
}
目标:创建 N1QL 查询,该查询将匹配给定 email
地址 AND data
属性 包含的所有文档给定的子字符串。
基本如下:
SELECT * FROM `bucket` WHERE `email` = 'A' AND `data` LIKE '%searchableValue%';
预期结果是第一个和第二个文档,因为符合条件。但是查询不起作用,因为数据不是文本类型,而是对象类型。如果 data
属性 是这样的:
{"data" : "this should be searchableValue!" }
查询将 return 预期结果。
问题是:
如何创建这样一个 return 预期结果的 N1QL 查询?
我知道 Couchbase 无法比较文本中的子字符串,但使用全文索引应该可以,因为 Couchbase 4.5+
Couchbase4.6 和 5.0 有 more/better 选项(解释如下)。在couchbase4.5中,可以使用Array Indexing来解决:
例如,使用 travel-sample
样本桶、数组索引和查询将执行您想要的那种子字符串搜索。
create index tmp_geo on `travel-sample`(DISTINCT ARRAY x FOR x IN object_values(geo) END) where type = "airport";
select meta().id, geo from `travel-sample` where type = "airport"
and ANY x IN object_values(geo) SATISFIES to_string(x) LIKE "12%" END;
N1QL 在 4.6 中引入了一个函数 TOKENS(),它可以帮助您在标记化 sub-objects 上创建功能索引(而不是上面示例中的数组索引):
https://dzone.com/articles/more-than-like-efficient-json-search-with-couchbas
而且,Couchbase 5.0 开发人员版本 (https://blog.couchbase.com/2017/january/introducing-developer-builds) 具有 N1QL 函数 CURL(),它允许您访问任何 HTTP/REST 端点作为 N1QL 查询的一部分(因此,可以访问 FTS端点)。有关详细信息和示例,请参阅以下博客:
- https://blog.couchbase.com/2017/january/developer-release--curl-n1ql
- https://dzone.com/articles/curl-comes-to-n1ql-querying-external-json-data
顺便说一句,你能澄清一下你是想在查询中使用部分标记还是只需要完整标记吗?
-普拉萨德
以下是根据@prasad 的回答进行的具体查询。
使用 Couchbase 4.5:
CREATE INDEX idx_email ON `bucket`( email );
SELECT *
FROM `bucket`
WHERE
`email` = 'A'
AND ANY t WITHIN `data` SATISFIES t LIKE '%searchableValue%' END;
使用 Couchbase 4.6:
CREATE INDEX idx_email ON `bucket`( email );
CREATE INDEX idx_tokens ON `bucket`( DISTINCT ARRAY t FOR t IN TOKENS( `data` ) END );
SELECT *
FROM `bucket`
WHERE
`email` = 'A'
AND ANY t IN TOKENS( `data` ) SATISFIES t = 'searchableValue' END;
考虑以下文档并考虑在以下文档上创建全文索引:
{
email : "A",
"data" : {
"dynamic_property" : "ANY_TYPE",
"dynamic_property2" : {
"property" : "searchableValue"
},
"field" : "VALUE"
}
},
{
email : "B",
"data" : {
"other_dynamic_prop" : "test-searchableValue-2",
}
},
{
email : "A",
"data" : {
"thirdDynamicProp" : {
"childProp" : "this should be searchableValue!"
}
}
}
目标:创建 N1QL 查询,该查询将匹配给定 email
地址 AND data
属性 包含的所有文档给定的子字符串。
基本如下:
SELECT * FROM `bucket` WHERE `email` = 'A' AND `data` LIKE '%searchableValue%';
预期结果是第一个和第二个文档,因为符合条件。但是查询不起作用,因为数据不是文本类型,而是对象类型。如果 data
属性 是这样的:
{"data" : "this should be searchableValue!" }
查询将 return 预期结果。
问题是: 如何创建这样一个 return 预期结果的 N1QL 查询?
我知道 Couchbase 无法比较文本中的子字符串,但使用全文索引应该可以,因为 Couchbase 4.5+
Couchbase4.6 和 5.0 有 more/better 选项(解释如下)。在couchbase4.5中,可以使用Array Indexing来解决:
例如,使用 travel-sample
样本桶、数组索引和查询将执行您想要的那种子字符串搜索。
create index tmp_geo on `travel-sample`(DISTINCT ARRAY x FOR x IN object_values(geo) END) where type = "airport";
select meta().id, geo from `travel-sample` where type = "airport"
and ANY x IN object_values(geo) SATISFIES to_string(x) LIKE "12%" END;
N1QL 在 4.6 中引入了一个函数 TOKENS(),它可以帮助您在标记化 sub-objects 上创建功能索引(而不是上面示例中的数组索引):
https://dzone.com/articles/more-than-like-efficient-json-search-with-couchbas
而且,Couchbase 5.0 开发人员版本 (https://blog.couchbase.com/2017/january/introducing-developer-builds) 具有 N1QL 函数 CURL(),它允许您访问任何 HTTP/REST 端点作为 N1QL 查询的一部分(因此,可以访问 FTS端点)。有关详细信息和示例,请参阅以下博客: - https://blog.couchbase.com/2017/january/developer-release--curl-n1ql - https://dzone.com/articles/curl-comes-to-n1ql-querying-external-json-data
顺便说一句,你能澄清一下你是想在查询中使用部分标记还是只需要完整标记吗?
-普拉萨德
以下是根据@prasad 的回答进行的具体查询。
使用 Couchbase 4.5:
CREATE INDEX idx_email ON `bucket`( email );
SELECT *
FROM `bucket`
WHERE
`email` = 'A'
AND ANY t WITHIN `data` SATISFIES t LIKE '%searchableValue%' END;
使用 Couchbase 4.6:
CREATE INDEX idx_email ON `bucket`( email );
CREATE INDEX idx_tokens ON `bucket`( DISTINCT ARRAY t FOR t IN TOKENS( `data` ) END );
SELECT *
FROM `bucket`
WHERE
`email` = 'A'
AND ANY t IN TOKENS( `data` ) SATISFIES t = 'searchableValue' END;