过滤数组包含任何给定值的项目
Filter items which array contains any of given values
我有一组文档,例如
{
tags:['a','b','c']
// ... a bunch properties
}
如标题所述:有没有办法使用 Nest 过滤包含任何给定标签的所有文档?
例如,上面的记录将匹配 ['c','d']
或者我应该手动构建多个 "OR" 吗?
编辑:下面的 bitset 内容可能很有趣,但答案本身有点过时。 2.x 中的某些功能正在发生变化。 Slawek 在另一个答案中也指出,在这种情况下,terms
查询是干掉搜索的一种简单方法。最后重构为当前的最佳实践。 —nz
您可能需要 Bool Query (or more likely Filter 和另一个查询),以及 should
子句。
bool 查询具有三个主要属性:must
、should
和 must_not
。其中每一个都接受另一个查询或查询数组。子句名称是不言自明的;在您的情况下,should
子句可以指定一个列表过滤器,与其中任何一个的匹配都将 return 您要查找的文档。
来自文档:
In a boolean query with no must
clauses, one or more should
clauses must match a document. The minimum number of should clauses to match can be set using the minimum_should_match
parameter.
这里有一个 Bool 查询孤立的例子:
{
"bool": {
"should": [
{ "term": { "tag": "c" }},
{ "term": { "tag": "d" }}
]
}
}
这里是 Bool 查询的另一个示例,作为更通用 Filtered Query:
中的过滤器
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"bool": {
"should": [
{ "term": { "tag": "c" }},
{ "term": { "tag": "d" }}
]
}
}
}
}
是否将 Bool 用作查询(例如,影响匹配分数)或用作过滤器(例如,减少随后被评分或 post-过滤的命中)是主观的, 取决于您的要求。
通常最好使用 Bool 而不是 Or Filter,除非您有使用 And/Or/Not 的理由(确实存在这样的理由)。 Elasticsearch 博客提供了有关每种不同实现的更多信息,以及您可能更喜欢 Bool 而不是 And/Or/Not 的好例子,反之亦然。
Elasticsearch 博客:All About Elasticsearch Filter Bitsets
更新重构查询...
现在,所有 that 都已完成,terms
查询是上述所有内容的 DRYer 版本。它在后台就查询类型做了正确的事情,它的行为与使用 minimum_should_match
选项的 bool
+ should
相同,总体上更简洁一些。
这是对最后一个查询进行了一些重构:
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"terms": {
"tag": [ "c", "d" ],
"minimum_should_match": 1
}
}
}
}
弹性搜索 2.0.1:
还有 terms query 应该可以为您省去一些工作。这里的例子来自文档:
{
"terms" : {
"tags" : [ "blue", "pill" ],
"minimum_should_match" : 1
}
}
在引擎盖下它构造了布尔值 should。所以它基本上和上面一样,但更短。
还有对应的terms filter.
因此,总结您的查询可能如下所示:
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"terms": {
"tags": ["c", "d"]
}
}
}
}
如果标签数量更多,长度可能会有很大差异。
虽然这是一个老问题,但我最近 运行 亲自解决了这个问题,这里的一些答案现在已被弃用(正如评论所指出的)。因此,为了其他可能在这里跌跌撞撞的人的利益:
term
查询可用于查找反向索引中指定的确切术语:
{
"query": {
"term" : { "tags" : "a" }
}
来自文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
或者,您可以使用 terms
查询,它将所有文档与给定数组中指定的任何项目进行匹配:
{
"query": {
"terms" : { "tags" : ["a", "c"]}
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html
需要注意的一个问题(这让我很困惑)- 定义文档的方式也会有所不同。如果您正在搜索的字段已被索引为 text
类型,那么 Elasticsearch 将执行全文搜索(即使用 analyzed
字符串)。
如果您将该字段编入索引为 keyword
,则会使用 'non-analyzed' 字符串执行关键字搜索。这可能会产生巨大的实际影响,因为已分析的字符串经过预处理(小写、标点符号删除等)请参阅 (https://www.elastic.co/guide/en/elasticsearch/guide/master/term-vs-full-text.html)
To avoid these issues, the string field has split into two new types: text, which should be used for full-text search, and keyword, which should be used for keyword search. (https://www.elastic.co/blog/strings-are-dead-long-live-strings)
你应该使用Terms Query
{
"query" : {
"terms" : {
"tags" : ["c", "d"]
}
}
}
对于那些在 2020 年查看此内容的人,您可能会注意到已接受的答案在 2020 年已被弃用,但可以使用 terms_set
和 minimum_should_match_script
组合使用类似的方法。
请参阅 SO 线程
中的详细答案
我有一组文档,例如
{
tags:['a','b','c']
// ... a bunch properties
}
如标题所述:有没有办法使用 Nest 过滤包含任何给定标签的所有文档?
例如,上面的记录将匹配 ['c','d']
或者我应该手动构建多个 "OR" 吗?
编辑:下面的 bitset 内容可能很有趣,但答案本身有点过时。 2.x 中的某些功能正在发生变化。 Slawek 在另一个答案中也指出,在这种情况下,terms
查询是干掉搜索的一种简单方法。最后重构为当前的最佳实践。 —nz
您可能需要 Bool Query (or more likely Filter 和另一个查询),以及 should
子句。
bool 查询具有三个主要属性:must
、should
和 must_not
。其中每一个都接受另一个查询或查询数组。子句名称是不言自明的;在您的情况下,should
子句可以指定一个列表过滤器,与其中任何一个的匹配都将 return 您要查找的文档。
来自文档:
In a boolean query with no
must
clauses, one or moreshould
clauses must match a document. The minimum number of should clauses to match can be set using theminimum_should_match
parameter.
这里有一个 Bool 查询孤立的例子:
{
"bool": {
"should": [
{ "term": { "tag": "c" }},
{ "term": { "tag": "d" }}
]
}
}
这里是 Bool 查询的另一个示例,作为更通用 Filtered Query:
中的过滤器{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"bool": {
"should": [
{ "term": { "tag": "c" }},
{ "term": { "tag": "d" }}
]
}
}
}
}
是否将 Bool 用作查询(例如,影响匹配分数)或用作过滤器(例如,减少随后被评分或 post-过滤的命中)是主观的, 取决于您的要求。
通常最好使用 Bool 而不是 Or Filter,除非您有使用 And/Or/Not 的理由(确实存在这样的理由)。 Elasticsearch 博客提供了有关每种不同实现的更多信息,以及您可能更喜欢 Bool 而不是 And/Or/Not 的好例子,反之亦然。
Elasticsearch 博客:All About Elasticsearch Filter Bitsets
更新重构查询...
现在,所有 that 都已完成,terms
查询是上述所有内容的 DRYer 版本。它在后台就查询类型做了正确的事情,它的行为与使用 minimum_should_match
选项的 bool
+ should
相同,总体上更简洁一些。
这是对最后一个查询进行了一些重构:
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"terms": {
"tag": [ "c", "d" ],
"minimum_should_match": 1
}
}
}
}
弹性搜索 2.0.1:
还有 terms query 应该可以为您省去一些工作。这里的例子来自文档:
{
"terms" : {
"tags" : [ "blue", "pill" ],
"minimum_should_match" : 1
}
}
在引擎盖下它构造了布尔值 should。所以它基本上和上面一样,但更短。
还有对应的terms filter.
因此,总结您的查询可能如下所示:
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"terms": {
"tags": ["c", "d"]
}
}
}
}
如果标签数量更多,长度可能会有很大差异。
虽然这是一个老问题,但我最近 运行 亲自解决了这个问题,这里的一些答案现在已被弃用(正如评论所指出的)。因此,为了其他可能在这里跌跌撞撞的人的利益:
term
查询可用于查找反向索引中指定的确切术语:
{
"query": {
"term" : { "tags" : "a" }
}
来自文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
或者,您可以使用 terms
查询,它将所有文档与给定数组中指定的任何项目进行匹配:
{
"query": {
"terms" : { "tags" : ["a", "c"]}
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html
需要注意的一个问题(这让我很困惑)- 定义文档的方式也会有所不同。如果您正在搜索的字段已被索引为 text
类型,那么 Elasticsearch 将执行全文搜索(即使用 analyzed
字符串)。
如果您将该字段编入索引为 keyword
,则会使用 'non-analyzed' 字符串执行关键字搜索。这可能会产生巨大的实际影响,因为已分析的字符串经过预处理(小写、标点符号删除等)请参阅 (https://www.elastic.co/guide/en/elasticsearch/guide/master/term-vs-full-text.html)
To avoid these issues, the string field has split into two new types: text, which should be used for full-text search, and keyword, which should be used for keyword search. (https://www.elastic.co/blog/strings-are-dead-long-live-strings)
你应该使用Terms Query
{
"query" : {
"terms" : {
"tags" : ["c", "d"]
}
}
}
对于那些在 2020 年查看此内容的人,您可能会注意到已接受的答案在 2020 年已被弃用,但可以使用 terms_set
和 minimum_should_match_script
组合使用类似的方法。
请参阅 SO 线程
中的详细答案