【问题标题】:Elasticsearch array must and must_notElasticsearch 数组必须和 must_not
【发布时间】:2014-02-05 17:58:40
【问题描述】:

我的 elasticsearch DB 中有一个类似这样的文档:

{
   "tags"   =>   [
      "tag-1",
      "tag-2",
      "tag-3",
      "tag-A"
   ]
   "created_at"   =>"2013-07-02 12:42:19   UTC",
   "label"   =>"Mon super label"
}

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

我尝试使用 bool 过滤器,但无法使其正常工作!

【问题讨论】:

    标签: elasticsearch filtering


    【解决方案1】:

    这是一种似乎可以实现您想要的方法:http://sense.qbox.io/gist/4dd806936f12a9668d61ce63f39cb2c284512443

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

    curl -XPUT "http://localhost:9200/test_index" -d'
    {
        "mappings": {
            "docs" : {
                "properties": {
                    "tags" : {
                        "type": "string",
                        "index": "not_analyzed"
                    },
                    "label" : {
                        "type": "string"
                    }
                }
            }
        }
    }'
    

    然后添加一些文档:

    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 子句进行查询,如下所示:

    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"
                          }
                      }
                   ]
                }
             }
          }
       }
    }'
    

    产生正确的结果:

    {
       "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,如果您在 localhost:9200 安装并运行 ES,您可以使用它,或者您可以提供自己的端点。

    【讨论】:

      猜你喜欢
      • 2018-04-06
      • 2019-07-22
      • 2019-06-10
      • 1970-01-01
      • 2015-11-02
      • 2020-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多