【问题标题】:Filter Elasticsearch Aggregation by Bucket Key Value按桶键值过滤 Elasticsearch 聚合
【发布时间】:2017-11-23 14:59:08
【问题描述】:

我有一个文档的 Elasticsearch 索引,其中有一个包含 URL 列表的字段。正如预期的那样,在此字段上进行聚合可以让我计算出唯一 URL 的数量。

GET models*/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "links": {
      "terms": {
        "field": "links.keyword",
        "size": 10
      }
    }
  }
}

然后我想过滤掉其键不包含特定字符串的存储桶。我试过用Bucket Selector Aggregation这样做。

这次尝试:

GET models*/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "links": {
      "terms": {
        "field": "links.keyword",
        "size": 10
      }
    },
    "links_key_filter": {
      "bucket_selector": {
        "buckets_path": {
          "key": "links"
        },
        "script": "!key.contains('foo')"
      }
    }
  }
}

失败:

名为 [links_key_filter] 类型的无效管道聚合 [桶选择器]。仅允许同级管道聚合 顶层

将桶选择器放在链接聚合中,如下所示:

GET models*/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "links": {
      "terms": {
        "field": "links.keyword",
        "size": 10
      },
      "bucket_selector": {
        "buckets_path": {
          "key": "links"
        },
        "script": "!key.contains('foo')"
      }
    }
  }
}

失败:

在[links]中找到两个聚合类型定义:[terms]和[bucket_selector]

我会继续修修补补,但现在有点卡住了:(

【问题讨论】:

  • 我认为在第二种情况下,您缺少 aggs 聚合应该去的 links_key_filter 部分
  • 你能弄明白吗?你是怎么做到的?

标签: elasticsearch key-value aggregation bucket


【解决方案1】:

将无法使用bucket_selector,因为它的bucket_path

必须引用数字值或单值数字度量聚合[source]

terms 聚合产生的内容被表示为StringTerms——不管你是否force a placeholder multibucket aggregation,这根本行不通。

话虽如此,每个terms 聚合都支持exclude filter

假设您的链接是关键字数组:

POST models/_doc/1
{
  "links": [
    "google.com",
    "wikipedia.org"
  ]
}

POST models/_doc/2
{
  "links": [
    "reddit.com",
    "google.com"
  ]
}

如果您想对除reddit 之外的所有内容进行分组,您可以使用以下正则表达式:

POST models*/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "links": {
      "terms": {
        "field": "links.keyword",
        "exclude": ".*reddit.*",    <-- 
        "size": 10
      }
    }
  }
}

顺便说一句,使用此类正则表达式会产生一些重要的影响,尤其是。当您想象一个区分大小写的场景时,您需要查询时生成的正则表达式——正如How to correctly query inside of terms aggregate values in elasticsearch, using include and regex?中所讨论的@

【讨论】:

    【解决方案2】:
    GET models*/_search
    {
      "query": {
        "match_all": {}
      },
      "size": 0,
      "aggs": {
        "links": {
          "terms": {
            "field": "links.keyword",
            "size": 10
          }
    
        },
          "bucket_selector": {
            "buckets_path": {
              "key": "links"
            },
            "script": "!key.contains('foo')"
          }
      }
    }
    

    您的选择器应该升级,它应该直接在 aggs 中并与您的选择器组平行。 我不确定密钥过滤

    【讨论】:

      【解决方案3】:

      您可以使用“_key”来获取密钥:

      GET models*/_search
      {
        "query": {
          "match_all": {}
        },
        "size": 0,
        "aggs": {
          "links": {
            "terms": {
              "field": "links.keyword",
              "size": 10
            },
            "bucket_selector": {
              "buckets_path": {
                "key": "_key"
              },
              "script": "!params.key.contains('foo')"
            }
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-12-04
        • 2018-09-14
        • 1970-01-01
        • 2017-04-15
        • 2019-07-05
        • 1970-01-01
        • 2015-10-06
        • 2021-08-04
        • 2019-03-03
        相关资源
        最近更新 更多