Elasticsearch排除字段值最高的问题

时间:2018-07-16 11:21:14

标签: elasticsearch

{'country': 'France', 'collected': '2018-03-12', 'active': true}
{'country': 'France', 'collected': '2018-03-13', 'active': true}
{'country': 'France', 'collected': '2018-03-14', 'active': false}
{'country': 'Canada', 'collected': '2018-02-01', 'active': false}
{'country': 'Canada', 'collected': '2018-02-02', 'active': true}

假设我有这个结果集,并且我想按国家/地区对它们进行分组。将它们按国家分组后,将得到结果:

{'country': 'France', 'collected': '2018-03-14', 'active': false}
{'country': 'Canada', 'collected': '2018-02-02', 'active': true}

但是我想排除最后一行activefalse的结果(只要最后一行等于true,同一国家的旧行可以为true或false都无关紧要) ,如何在elasticsearch中做到这一点?这是我的查询:

POST /test/_search?search_type=count
{
    "aggs": {
        "group": {
            "terms": {
                "field": "country"
            },
            "aggs": {
                "group_docs": {
                    "top_hits": {
                        "size": 1,
                        "sort": [
                            {
                                "collected": {
                                    "order": "desc"
                                }
                            }
                        ]
                    }
                }
            }
        }
    }
}

4 个答案:

答案 0 :(得分:2)

我认为您可以通过按top_hits中的两个字段进行排序:按active和按collected进行排序。基本上,您希望true排在首位并且相等时,然后按collected排序。诸如此类的内容将始终显示按active:true排序的collected文档。

该解决方案的唯一缺点是,如果您没有任何活动文档,top_hits将显示一个active:false文档。

{
  "size": 0,
  "aggs": {
    "group": {
      "terms": {
        "field": "country"
      },
      "aggs": {
        "group_docs": {
          "top_hits": {
            "size": 1,
            "sort": [
              {
                "active": {
                  "order": "desc"
                }, 
                "collected": {
                  "order": "desc"
                }
              }
            ]
          }
        }
      }
    }
  }
}

答案 1 :(得分:0)

为什么不事先过滤它们:

POST /test/_search
{
  "query": {
    "bool": {
      "filter": [
        { 
          "term":{ 
            "active": true 
          }
        }
      ]
    }
  }, 
  "aggs": {
    "group": {
      "terms": {
        "field": "country"
      },
      "aggs": {
        "group_docs": {
            "top_hits": {
              "size": 2,
              "sort": [
                {
                  "collected": 
                  {"order":"desc"}
                }
              ]
            }
          }
        }
      }
    }
  }

此查询将按激活状态为真的县对您的数据进行分组。

更多信息:filter context

答案 2 :(得分:-1)

听起来您正在寻找过滤聚合结果的方法。我相信您需要使用 filter bucket for this

类似的东西:

{
    "aggs": {
        "group": {
            "terms": {
                "field": "country"
            },
            "filter": {
                "term": {
                    "active": true
                }
            },
            "aggs": {
                "group_docs": {
                    "top_hits": {
                        "size": 1,
                        "sort": [
                            {
                                "collected": {
                                    "order": "desc"
                                }
                            }
                        ]
                    }
                }
            }
        }
    }
}

答案 3 :(得分:-1)

通常,您可以根据需要嵌套聚合以实现任何结果。在这种情况下,在两者之间添加过滤器桶聚合应该可以达到预期的结果。

{
  "size": 0,
  "aggs": {
    "group": {
      "terms": { "field": "country" },
      "aggs": {
        "active_in_group": {
          "filter" : { "term": { "active": true } },
          "aggs": {
            "group_docs": {
              "top_hits": {
                "size": 1,
                "sort": [
                  { "collected": { "order": "desc" } }
                ]
              }
            }
          }
        }
      }
    }
  }
}

您在这里:

Agg级别1-条款存储区;结果集中每个国家(活跃或不活跃)的计数是多少

2级汇总-过滤桶;每个国家/地区范围内的活动项目数是多少

平均等级3-热门歌曲;每个国家/地区存储区中活动项的最高结果(根据您的排序,是最新收集的结果)是什么

如您所见,任何嵌套的聚合始终尊重其嵌套在其中的聚合。

我不清楚的一件事是,您是否希望每个国家/地区存储区中的计数仅反映活动项目,还是不活动项目,或者您根本不在乎计数?只是使用“桶”一词来获得每个国家/地区的热门歌曲。

如果您希望计数仅反映活动项,则反转该术语和过滤器聚合,如果希望计数包括活动和不活动,请保持此顺序。如果您不关心计数,则顺序无关紧要。

这当然会为您的结果(每个国家/地区中的有效项的数量)增加一定程度的汇总,但是在解析结果时应该很容易克服/忽略。

该解决方案已经过验证,可以在Elastic 6.X中使用,但是由于您使用的是在Elastic 2.x中不推荐使用的search_type = count,由于某些原因,我可以看到您仍必须使用Elastic1.x。由于这些特定的聚合在一段时间内没有发生变化,因此该解决方案仍然应该可以工作,但是由于弹性1.x太过时了,我无法验证自此以来没有出现任何错误或补丁。对于将来的参考,弹性因版本而异。您通常希望将版本包含在有关弹性的任何问题中,并在所有答案上检查版本。无论如何,我建议您进行升级。