【问题标题】:Elastic: How i can filter aggregation buckets by string key弹性:我如何通过字符串键过滤聚合桶
【发布时间】:2021-06-15 15:47:10
【问题描述】:

我有一些来自一个提供商的数据 - 非常大的结构化 JSON 数据:

  "mappings": {
    "properties": {
      "field_a": { .. },
      "field_b": { .. },
      "field_c": { .. },
      "field_d": {
        "properties": {
          "subfield_a": {...},
          "subfield_b": {...},
          "subfield_c": {...},
          "subfield_d": {...},
          "subfield_e": {
            "properties": {
              "myfield": {
                "type": "keyword"
              },
              "another_a": {...},
              "another_b": {...},
            }
          }
        }
      }
    }
  }

subfield_e 是对象数组,包含许多我感兴趣的字段“myfield”。

我需要只包含包含一些字符串的字段“myfield”的聚合。

所以,我现在这样做是错误的(但逻辑结果):

GET /index/_search
{
  "query": {
    "wildcard": {
      "field_d.subfield_e.myfield": "*string*"
    }
  },
    "aggs": {
      "interest": {
        "terms": {
          "field": "field_d.subfield_e.myfield",
          "size": 10
        }
      }
    },
    "size": 0
}

此查询的问题是,该查询将选择对象数组“esubfield_e”包含对象 myfield 和 string 的所有文档,并在这些文档下进行聚合。所以,最后我得到了这些文档下所有“myfields”的结果,而不仅仅是包含 string 的 myfields。

我试图在我的主要聚合之后创建一个 bucket_selector 聚合,但我得到了错误:“buckets_path 必须引用一个数字值或一个单值数字度量聚合,得到:[String] at aggregation [_key]”

我的代码灵感来自:Filter Elasticsearch Aggregation by Bucket Key Value,现在看起来:

GET /index/_search
{
  "query": {
    "wildcard": {
      "field_d.subfield_e.myfield": "*string*"
    }
  },
    "aggs": {
      "interest": {
        "terms": {
          "field": "field_d.subfield_e.myfield",
          "size": 10
        }
      },
      "aggs": {
        "buckets": {
          "bucket_selector": {
            "buckets_path": {
              "key": "_key"
            },
            "script": "params.key.contains('string')"
          }
        }
      }
    }
  },
  "size": 0
}

那么,我如何通过它们的字符串键过滤聚合桶(术语 aggs)?

【问题讨论】:

  • 我刚刚发布了an answer to the original question。如果您希望我根据您的特定用例进行调整,请告诉我!
  • 谢谢,我正在尝试,但它看起来像性能杀手。我现在也将数据重新导入另一个索引,在那里我尝试为 subfield_e 指定 type="nested"。如果我使用嵌套类型,我可以使用完美嵌套 + 过滤器聚合,并且它可以按我的需要工作。但问题是性能,所以我会在导入后告知。
  • 好的,好的。检查该答案底部的链接——它处理嵌套字段和部分匹配——它可能与你有关。无论如何,请告诉我进展如何!

标签: elasticsearch filter aggregation


【解决方案1】:

我通过将 subfield_e 切换到嵌套对象而不是未定义数组来解决它,并将所有数据重新导入到这个新映射中。

当前映射如下:

  "mappings": {
    "properties": {
      "field_a": { .. },
      "field_b": { .. },
      "field_c": { .. },
      "field_d": {
        "properties": {
          "subfield_a": {...},
          "subfield_b": {...},
          "subfield_c": {...},
          "subfield_d": {...},
          "subfield_e": {
            "type": "nested"    <======= This line added
            "properties": {
              "myfield": {
                "type": "keyword"
              },
              "another_a": {...},
              "another_b": {...},
            }
          }
        }
      }
    }
  }

最后的工作查询是:

GET /index/_search
{
  "query": {
    "nested": {
      "path": "field_d.subfield_e",
      "query": {
        "wildcard": {
          "field_d.subfield_e.myfield": {
            "value": "*string*"
          }
        }
      }
    }
  },
  "aggs": {
    "agg": {
      "nested": {
        "path": "field_d.subfield_e"
      },
      "aggs": {
        "inner": {
          "filter": {
            "wildcard": {
              "field_d.subfield_e.myfield": "*string*"
            }
          }, "aggs": {
            "interest": {
              "terms": {
                "field": "field_d.subfield_e.myfield",
                "size": 10
              }
            }
          }
        }
      }
    }
  },
  "size": 0
}

在我的情况下,这个查询的速度比在术语聚合中使用包含/排除要好得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 2021-07-03
    • 2017-04-15
    • 2015-10-18
    • 2020-06-20
    • 2020-02-01
    • 1970-01-01
    相关资源
    最近更新 更多