首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Elasticsearch数组必须和must_not

Elasticsearch数组必须和must_not
EN

Stack Overflow用户
提问于 2014-01-17 01:12:54
回答 1查看 26.1K关注 0票数 10

我的elasticsearch DB中有一个文档,如下所示:

代码语言:javascript
复制
{
   "tags"   =>   [
      "tag-1",
      "tag-2",
      "tag-3",
      "tag-A"
   ]
   "created_at"   =>"2013-07-02 12:42:19   UTC",
   "label"   =>"Mon super label"
}

我希望能够使用以下条件过滤我的文档:文档标签数组必须有标签-1、标签-3和标签-2,但不能有标签-A。

我试图使用一个布尔过滤器,但我不能设法使它工作!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-17 02:04:41

这里有一个方法似乎可以完成您想要的任务:http://sense.qbox.io/gist/4dd806936f12a9668d61ce63f39cb2c284512443

首先,我创建了一个带有显式映射的索引。我这样做是为了将"tags"属性设置为"index": "not_analyzed"。这意味着不会以任何方式修改文本,这将简化本例的查询过程。

代码语言:javascript
复制
curl -XPUT "http://localhost:9200/test_index" -d'
{
    "mappings": {
        "docs" : {
            "properties": {
                "tags" : {
                    "type": "string",
                    "index": "not_analyzed"
                },
                "label" : {
                    "type": "string"
                }
            }
        }
    }
}'

然后添加一些文档:

代码语言:javascript
复制
curl -XPUT "http://localhost:9200/test_index/docs/1" -d'
{
    "tags" : [
        "tag-1",
        "tag-2",
        "tag-3",
        "tag-A"
    ],
    "label" : "item 1"
}'
curl -XPUT "http://localhost:9200/test_index/docs/2" -d'
{
    "tags" : [
        "tag-1",
        "tag-2",
        "tag-3"
    ],
    "label" : "item 2"
}'
curl -XPUT "http://localhost:9200/test_index/docs/3" -d'
{
    "tags" : [
        "tag-1",
        "tag-2"
    ],
    "label" : "item 3"
}'

然后,我们可以在bool过滤器中使用mustmust_not子句进行查询,如下所示:

代码语言:javascript
复制
curl -XPOST "http://localhost:9200/test_index/_search" -d'
{
   "query": {
      "filtered": {
         "query": {
            "match_all": {}
         },
         "filter": {
            "bool": {
               "must": [
                  {
                     "terms": {
                        "tags": [
                           "tag-1",
                           "tag-2",
                           "tag-3"
                        ],
                        "execution" : "and"
                     }
                  }
               ],
               "must_not": [
                  {
                      "term": {
                         "tags": "tag-A"
                      }
                  }
               ]
            }
         }
      }
   }
}'

这将产生正确的结果:

代码语言:javascript
复制
{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 2,
      "successful": 2,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "docs",
            "_id": "2",
            "_score": 1,
            "_source": {
               "tags": [
                  "tag-1",
                  "tag-2",
                  "tag-3"
               ],
               "label": "item 2"
            }
         }
      ]
   }
}

请注意must子句中terms过滤器中的"execution" : "and"参数。这意味着只会返回指定了所有"tags"的文档(而不是那些与一个或多个匹配的文档)。这可能就是你错过的东西。您可以在ES docs中阅读有关这些选项的更多信息。

我制作了一个可运行的示例here,如果您安装了ES并在localhost:9200上运行,您可以使用它,或者您可以提供自己的端点。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21168375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档