【问题标题】:Post filter on subaggregation in elasticsearch在弹性搜索中对子聚合进行后过滤
【发布时间】:2016-04-27 01:53:51
【问题描述】:

我正在尝试对聚合数据运行后过滤器,但它没有按预期工作。有人可以查看我的查询并建议我是否在这里做错了什么。

    "query" : {
    "bool" : {
      "must" : {
        "range" : {
          "versionDate" : {
            "from" : null,
            "to" : "2016-04-22T23:13:50.000Z",
            "include_lower" : false,
            "include_upper" : true
          }
        }
      }
    }
  },
  "aggregations" : {
    "associations" : {
      "terms" : {
        "field" : "association.id",
        "size" : 0,
        "order" : {
          "_term" : "asc"
        }
      },
      "aggregations" : {
        "top" : {
          "top_hits" : {
            "from" : 0,
            "size" : 1,
            "_source" : {
              "includes" : [ ],
              "excludes" : [ ]
            },
            "sort" : [ {
              "versionDate" : {
                "order" : "desc"
              }
            } ]
          }
        },
        "disabledDate" : {
          "filter" : {
            "missing" : {
              "field" : "disabledDate"
            }
          }
        }
      }
    }
  }
}

查询中的步骤:

  1. 按小于或等于给定日期的 indexDate 过滤。
  2. 基于 formId 聚合。根据 formId 形成存储桶。
  3. 按降序排序并返回每个桶的最高命中结果。
  4. 在排序子聚合之后运行子聚合过滤器,并从禁用日期不为空的存储桶中删除所有文档。(这不起作用)

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    post_filter 的全部目的是聚合计算完毕后运行。因此,post_filter 对聚合结果没有任何影响。

    在您的情况下,您可以做的是应用顶级 filter aggregation 以便在聚合中不考虑没有 disabledDate 的文档,即只考虑 with @987654327 的文档@。

    {
      "query": {
        "bool": {
          "must": {
            "range": {
              "versionDate": {
                "from": null,
                "to": "2016-04-22T23:13:50.000Z",
                "include_lower": true,
                "include_upper": true
              }
            }
          }
        }
      },
      "aggregations": {
        "with_disabled": {
          "filter": {
            "exists": {
              "field": "disabledDate"
            }
          },
          "aggs": {
            "form.id": {
              "terms": {
                "field": "form.id",
                "size": 0
              },
              "aggregations": {
                "top": {
                  "top_hits": {
                    "size": 1,
                    "_source": {
                      "includes": [],
                      "excludes": []
                    },
                    "sort": [
                      {
                        "versionDate": {
                          "order": "desc"
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
    

    【讨论】:

    • 我的用例需要在计算聚合时考虑带有 disabledDate!=null 的文档。一旦聚合完成,我想从所有存储桶中过滤所有带有 disabledDate!=null 的文档。所以我试图在聚合完成后执行一个后过滤器,以返回缺少 disabledDate 的文档,它是 disabled==null。
    • 在计算完聚合之后,您无法从存储桶中删除任何内容。使用查询和过滤器,您只能决定哪组文档将进入聚合管道,但是一旦计算了聚合,您就无法修改存储桶。
    • 感谢您解除疑问。我的用例是,在我对聚合存储桶执行 tophit 之后,如果存储桶有一个 disabledDate!=null 的文档,我不想从该存储桶返回任何结果。考虑 V1 已禁用并且最接近给定时间,它是以 tophit 的形式返回。如果我执行后过滤器,则不应从该存储桶返回任何内容。这就是要求。但是,如果我在聚合之前过滤 V1 文档,则可能会返回 V2,它是来自同一存储桶的下一个最接近给定时间的文档。我如何实现这一目标?我得到了这个在 SQL 中的工作。
    • 这可能是一个愚蠢的问题,但我可以在排序完成后添加一个子聚合以仅过滤缺少的 disabledDate 吗?我试过了,但它似乎不起作用。我已经相应地更新了问题。
    猜你喜欢
    • 2019-07-25
    • 1970-01-01
    • 2021-07-03
    • 2020-06-20
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    相关资源
    最近更新 更多