我有一组类似以下的文件:
{
tags:['a','b','c']
// ... a bunch properties
}
如标题所述:是否有一种方法可以使用Nest过滤包含任何给定标签的所有文档?
例如,上面的记录将匹配['c','d']
或者我应该手动构建多个“OR”吗?
我有一组类似以下的文件:
{
tags:['a','b','c']
// ... a bunch properties
}
如标题所述:是否有一种方法可以使用Nest过滤包含任何给定标签的所有文档?
例如,上面的记录将匹配['c','d']
或者我应该手动构建多个“OR”吗?
elasticsearch 2.0.1:
还有terms query可以帮你省去一些工作。这是来自文档的例子:
{
"terms" : {
"tags" : [ "blue", "pill" ],
"minimum_should_match" : 1
}
}
在幕后它构建布尔should语句。因此,基本上与上面的内容相同,只是更短。
还有一个对应的terms过滤器。
因此,总结一下,您的查询可能如下所示:
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"terms": {
"tags": ["c", "d"]
}
}
}
}
标签数量越多,这可能会导致长度的相当大的差异。
编辑:下面的bitset内容可能是一段有趣的阅读,但是答案本身有点过时。在2.x版本中,某些功能正在发生变化。此外,Slawek在另一个回答中指出,terms
查询是在这种情况下DRY(不重复原则)搜索的简单方法。最佳实践已在最后进行了重构。—nz
您可能需要一个布尔查询(或更可能与另一个查询一起使用过滤器),其中包含一个should
子句。
布尔查询具有三个主要属性:must
、should
和must_not
。每个属性都接受另一个查询或查询数组。这些子句名称相当自解释;在您的情况下,should
子句可以指定一个过滤器列表,其中任何一个匹配项将返回您要查找的文档。
来自文档的摘录:
在没有
must
子句的布尔查询中,一个或多个should
子句必须匹配文档。可以使用minimum_should_match
参数设置应匹配的最小子句数。
以下是该Bool查询在独立情况下的示例:
{
"bool": {
"should": [
{ "term": { "tag": "c" }},
{ "term": { "tag": "d" }}
]
}
}
这里是布尔查询作为筛选器在更常见的过滤查询中的另一个示例:
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"bool": {
"should": [
{ "term": { "tag": "c" }},
{ "term": { "tag": "d" }}
]
}
}
}
}
无论你将 Bool 用作查询(例如,影响匹配的得分),还是用作过滤器(例如,减少随后被评分或过滤的命中数)都是主观的,取决于你的需求。
通常情况下,与使用 Or 过滤器 相比,最好使用 Bool,除非你有理由使用 And/Or/Not(确实存在这样的理由)。Elasticsearch 博客提供了有关每种实现方式的更多信息,并且给出了何时可能更喜欢 Bool 而不是 And/Or/Not 以及反之的好例子。
Elasticsearch 博客:All About Elasticsearch Filter Bitsets
更新为重新构造的查询...
现在,把所有那些东西都放到一边,terms
查询是以上所有内容的简化版。它在内部处理了正确的查询类型,使用 minimum_should_match
选项时与 bool
+ should
的行为相同,总体上更加简洁。
以下是稍微重构一下的最后一个查询:
{
"filtered": {
"query": {
"match": { "title": "hello world" }
},
"filter": {
"terms": {
"tag": [ "c", "d" ],
"minimum_should_match": 1
}
}
}
}
虽然这是一个老问题,但最近我自己遇到了这个问题,这里的一些答案现在已经过时了(正如评论所指出的)。因此,为了让其他可能会遇到这个问题的人受益:
可以使用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 将执行全文搜索(即使用分析过的字符串)。如果你将该字段索引为keyword
,则将执行使用“非分析”字符串的关键字搜索。这可能会产生巨大的实际影响,因为分析过的字符串是经过预处理的(小写化、标点符号删除等)。请参见(https://www.elastic.co/guide/en/elasticsearch/guide/master/term-vs-full-text.html)
为避免这些问题,字符串字段已拆分为两种新类型:text,应用于全文搜索;keyword,应用于关键字搜索。(https://www.elastic.co/blog/strings-are-dead-long-live-strings)
对于那些在2020年以后查看此内容的人,您可能会注意到接受的答案已经过时了,但是可以使用类似的方法组合使用terms_set
和minimum_should_match_script
来解决。
请查看SO线程中此详细回答
您应该使用Terms Query进行 IT 技术相关内容的查询。
{
"query" : {
"terms" : {
"tags" : ["c", "d"]
}
}
}
mustNot
子句中使用完全相同的“terms”条件,则会搜索所有不具有任何标签的文档。 - slawekminimum_should_match
现在只是terms_set
查询的一部分。 - Jason Smiley