即使字段的映射位于“文本”和“关键字”类型上,如何对“ sum”和“ avg”进行汇总?

时间:2019-10-02 05:56:05

标签: elasticsearch

我正在尝试对我的Elasticsearch查询执行sumavg聚合,一切工作都很好,但是我遇到了一个问题-我想对我的{ nested / text类型的{1}}个字段。

之所以如此,是因为如果需要这些特定的嵌套字段和子字段,则在执行keyword API时将使用keywords分析器。

这是我的地图:

search

请关注"eng" : { "type" : "nested", "properties" : { "date_updated" : { "type" : "long" }, "soc_angry_count" : { "type" : "float" }, "soc_comment_count" : { "type" : "float" }, "soc_dislike_count" : { "type" : "float" }, "soc_eng_score" : { "type" : "float" }, "soc_er_score" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "soc_haha_count" : { "type" : "float" }, "soc_kf_score" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "soc_like_count" : { "type" : "float" }, "soc_love_count" : { "type" : "float" }, "soc_mm_score" : { "type" : "float" }, "soc_sad_count" : { "type" : "float" }, "soc_save_count" : { "type" : "float" }, "soc_share_count" : { "type" : "float" }, "soc_te_score" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "soc_view_count" : { "type" : "float" }, "soc_wow_count" : { "type" : "float" } } } 嵌套字段的soc_er_scoresoc_kf_scoresoc_te_score子字段...

当我执行以下aggs时,它工作正常:

eng

这里是完成'aggs' => [ 'ENGAGEMENT' => [ 'nested' => [ 'path' => "eng" ], 'aggs' => [ 'ARTICLES' => [ //Use Histogram because the pub_date is of //long data type //Use interval 86400 to represent 1 day 'histogram' => [ 'field' => "eng.date_updated", "interval" => "86400", ], 'aggs'= [ 'SUM' => [ 'sum' => [ "field" => "eng.soc_like_score" ] ] ] ] ] ] ] API之后的输出

enter image description here

但是,如果查询是这样的:

search

输出看起来像这样:

enter image description here

执行的解决方案

解决方案1(用于确认)
在阅读了一些详尽的论坛讨论后,我了解到可以进行基于Java的解析,但似乎无法正常工作

这是我修改后的查询:

'aggs' => [
    'ENGAGEMENT' => [
        'nested' => [
            'path' => "eng"
        ],
        'aggs' => [
            'ARTICLES' => [
                //Use Histogram because the pub_date is of
                //long data type
                //Use interval 86400 to represent 1 day
                'histogram' => [
                    'field'  => "eng.date_updated",
                    "interval" => "86400",
                ],
                'aggs'= [
                    'SUM' => [
                        'sum' => [
                            "field" => "eng.soc_te_score"
                        ]
                    ]
                ]
            ]
        ]
    ]
]

但不幸的是,它以 null 0 'aggs'= [ 'SUM' => [ 'sum' => [ "field" => "Float.parseFloat(eng.soc_te_score).value" ] ] ]

响应

enter image description here

顺便说一句,我使用Laravel作为我的Web框架,这就是为什么这就是我的调试器或错误消息窗口的样子

请请求帮助,在此先谢谢您!

2 个答案:

答案 0 :(得分:1)

除了关键字one之外,我还将创建另一个数字子字段。因此,您可以将关键字字段用于搜索,将数字字段用于聚合。

例如,如下修改映射:

"soc_er_score" : {
  "type" : "text",
  "fields" : {
    "keyword" : {
      "type" : "keyword",
      "ignore_above" : 256
    },
    "numeric" : {
      "type" : "long",
      "ignore_malformed": true
    }
  }
},

然后您可以使用:

  • soc_er_score用于全文搜索
  • soc_er_score.keyword用于排序,术语汇总和精确匹配
  • soc_er_score.numeric用于sum和其他度量聚合。

如果索引中已经有数据,只需添加新的子字段即可修改映射,如下所示:

PUT my-index/_mapping/doc
{
  "properties": {
    "eng": {
      "soc_er_score" : {
        "type" : "text",
        "fields" : {
          "keyword" : {
            "type" : "keyword",
            "ignore_above" : 256
          },
          "numeric" : {
            "type" : "long",
            "ignore_malformed": true
          }
        }
      }
    }
  }
}

然后调用update by query endpoint以获取新的映射:

POST my-index/_update_by_query

完成后,eng.soc_er_score.numeric字段将为所有现有文档建立索引。

答案 1 :(得分:0)

我可以使用以下简单脚本解决问题:

"aggs" = [
    'SUM' => [
        'sum' => [
            "script" => "Float.parseFloat(doc['eng.soc_te_score.keyword'].value)"
        ]
    ]
];

有了这个,即使我的嵌套字段是textkeyword类型,我仍然可以为它们的 average sum < / p>