当前位置: 首页 > 知识库问答 >
问题:

Elasticsearch中的多字段聚合

苏宏峻
2023-03-14

我在elasticsearch中有一个文档索引,每个文档有480个字段。我试图做的是搜索一个词(例如“Apple”),并获得所有其值与搜索词匹配的唯一字段名。所以如果我的文档是:

{
  "field1": "123",
  "field2": "apple stock",
  "field3": "red apple",
},
{
  "field1": "apple",
  "field2": "apple stock",
  "field3": "green apple",
}

作为查询的结果,我希望得到如下所示的聚合:

{
  "field1": ["apple"],
  "field2": ["apple stock"],
  "field3": ["red apple", "green apple"]
}

由于每个文档都有480个字段,所以我更喜欢执行multi_match查询,而不是使用包含所有字段的筛选器:

"query": {
        "multi_match": {
            "query": "apple",
            "type": "phrase"
        }
    }

这个查询在ElasticSearch中可能吗?

共有1个答案

司立果
2023-03-14

由于您“不知道您不知道什么”,您可能不得不求助于脚本化的度量聚合:

POST myindex/_search
{
  "size": 0,
  "query": {
    "multi_match": {
      "query": "apple",
      "type": "phrase"
    }
  },
  "aggs": {
    "fields_breakdown": {
      "scripted_metric": {
        "params": {
          "phrase": "apple"
        }, 
        "init_script": "state.key_map = [:];",
        "map_script": """
          for (def pair : params._source.entrySet()) {
            def val = pair.getValue();
            
            if (!(val instanceof String) || !val.toLowerCase().contains(params.phrase.toLowerCase())) {
              continue;
            }
            
            def key = pair.getKey();
            
            if (!state.key_map.containsKey(key)) {
              state.key_map[key] = [val];
            } else if (!state.key_map[key].contains(val)) {
              state.key_map[key].add(val);
            }
          }
        """,
        "combine_script": "return state",
        "reduce_script": "return states"
      }
    }
  }
}

这段代码不能很好地伸缩(取决于您的索引大小),所以要小心使用它,也许可以分批使用(使用更严格的查询,或者限制一次聚合的字段数)。

顺便说一句,我之前提出了一个在类术语聚合中过滤子字符串的解决方案--它可能与这里的您相关。

 类似资料:
  • 这个问题不是如何通过多个字段进行聚合,我们可以使用子聚合。 如果你知道SQL,我可以给你一个完美的解释: 我们能在Elasticsearch中实现这一点吗? 谢谢。

  • 我是Elasticsearch的新手,我的程序有问题。 为了将结果分组,如SQL中的“group by”语句。我使用了聚合。 但我意识到这里有一个问题需要解决。我使用以下语句对我的结果进行分组: 我的问题是:字段2和字段3的值取决于字段1的值,所以如果你可以得到字段1的值,你也可以得到字段2和字段3的值。因此,像上面这样进行聚合会花费很多时间来完成我的程序(我已经测试过它,并意识到它比只对字段1进

  • 问题内容: 我想在字段上使用stats或extended_stats聚合,但是找不到完成此操作的任何示例(即,似乎只能将聚合与实际文档字段一起使用)。 是否有可能计算出“元数据”在ElasticSearch查询响应每个命中字段请求集合(例如,,,,等等)? 我假设答案是“否”,因为未对类似字段进行索引… 问题答案: 注意:就最新版本的Elasticsearch而言,原始答案现在已过时。使用Groo

  • 问题内容: 我正在尝试创建一个脚本字段,该脚本字段将计算两个时间戳之间的时间差,然后在该脚本字段上聚合一个。 我首先尝试: 在合计平均值下产生价值。 然后我尝试了: 生成了一条错误消息,内容为:“在映射中找不到[timedifference]的字段” 问题答案: 简单地将脚本移到聚合上怎么样?

  • 问题内容: 有人可以告诉我如何编写将汇总(汇总和计数)有关我的文档内容的Python语句吗? 脚本 输出值 是什么原因造成的?“ aggregations”关键字是否错误?我还需要导入其他软件包吗?如果“出勤”索引中的文档有一个名为emailAddress的字段,我将如何计算哪些文档具有该字段的值? 问题答案: 首先。现在我注意到,我在这里写的内容实际上没有定义聚合。对我来说,有关如何使用它的文档

  • 问题内容: 我将此数据插入了Elasticsearch: 旁注:重现: 1)下载:http://wmo.co/20160928_es_query/bulk.json 2)执行:卷曲-s -XPOST ‘ 的http://本地主机:9200 /测试/外部/ _bulk漂亮 ‘ -数据二进制@ bulk.json 问题: 获取每个“位置”有多少记录的计数。 解决方案1:存储桶聚合..没有得到期望的结果