Elasticsearch只筛选多个匹配结果,而不是任何匹配结果

时间:2017-09-23 14:24:46

标签: elasticsearch

如何只使用所有多项搜索过滤匹配结果。我有这个示例表,其中titleid是一个映射int字段,personid是一个关键字:

titleid:1,personid:a
titleid:3,personid:a

titleid:1,personid:b
titleid:2,personid:b

titleid:1,personid:c
titleid:5,personid:c

结果显示:

titleid:1

使用类似这样的示例查询:

{query:
    {bool:
    {filter:
            {must:[
                    {terms : {fields: {personid:[a,b,c]}}
                 ]
            }}}}

我有以下结果:

titleid: 1,2,3,5

也许这会有所帮助,我在sql中进行了查询并得到了预期的结果。我所做的是要求查询给出与匹配搜索参数数量的titleid的总和。这只是为了更自我解释,这个想法是使用elasticsearch。

select titleid
from (
   select count(titleid) as title_count, titleid 
   from table1 
   where personid in ('a','b','c')
   group by titleid
) as vw 
where title_count = 3

1 个答案:

答案 0 :(得分:1)

如果您只想要titleid == 1personid == 'a'的记录,则可以对这两个字段进行过滤。只有boolean query使用mustshouldmost_not。使用过滤器,因为它按照定义过滤(例如,删除)它是must

"query": {
  "bool": {
    "filter": [
      {
        "term": {
          "titleId": { "value": 1 }
        } 
      },
      {
        "term": {
          "personid": { "value": "a" }
        }
      }
    ]
  }
}

<强> UPDATE ::

现在,您的问题似乎要过滤并aggregate您的结果,然后汇总这些结果。有一些metricsbucket聚合

使用bucket selector aggregation(这不是经过测试但如果不正确应该非常接近)

{
    "aggs" : {
        "title_id" : {
            "filter" : { "terms": { "personid": ["a","b","c"] } },
            "aggs" : {
                "id_count" : { "count" : { "field" : "titleid" } }
            }
        },      
        aggs": {
            "count_filter": {
               "bucket_selector": {
                  "buckets_path": {
                     "the_doc_count": "_count"
                  },
                  "script": "the_doc_count == 3"
               }
            }
         }  
    }
}

但是,请注意,Pipeline聚合对其他聚合产生的输出起作用,因此计算初始doc_counts所需的总工作量将是相同的。由于需要为每个输入桶执行脚本部分,因此对于高基数字段而言,操作可能会很慢,就像成千上万的术语一样。