使用术语聚合执行搜索时如何返回实际值(不是小写字母)?

Posted

技术标签:

【中文标题】使用术语聚合执行搜索时如何返回实际值(不是小写字母)?【英文标题】:How to return actual value (not lowercase) when performing search with terms aggregation? 【发布时间】:2019-01-10 20:26:41 【问题描述】:

我正在处理一个 ElasticSearch (6.2) 项目,其中 index 有许多 keyword 字段,并且使用 lowercase 过滤器对它们进行规范化,以执行不区分大小写的搜索。搜索工作正常并返回规范化字段的实际值(不是小写字母)。但是,聚合不会返回字段的实际值(返回小写字母)。

以下示例取自 ElasticSearch 文档。

https://www.elastic.co/guide/en/elasticsearch/reference/master/normalizer.html

创建索引:

PUT 指数 “设置”: “分析”: “规范化器”: “my_normalizer”: “类型”:“自定义”, "char_filter": [], “过滤器”:[“小写”,“asciifolding”] , “映射”: “_doc”: “特性”: “富”: “类型”:“关键字”, “规范化器”:“我的规范化器”

插入文档:

放置索引/_doc/1 “富”:“酒吧” 放置索引/_doc/2 “富”:“巴兹”

聚合搜索:

获取索引/_search “大小”:0, “聚合”: “foo_terms”: “条款”: “场”:“富”

结果:

“接受”:43, “超时”:假, “_shards”: “总数”:1, “成功”:1, “跳过”:0, “失败”:0 , “命中”: “总数”:3, “最大分数”:0.0, “命中”: “总数”:2, “最大分数”:0.47000363, “命中”:[ "_index": "索引", "_type": "_doc", “_id”:“1”, “_score”:0.47000363, “_资源”: “富”:“酒吧” , "_index": "索引", "_type": "_doc", “_id”:“2”, “_score”:0.47000363, “_资源”: “富”:“巴兹” ] , “聚合”: “foo_terms”: “doc_count_error_upper_bound”:0, “sum_other_doc_count”:0, “桶”:[ “键”:“酒吧”, “文档计数”:1 , “关键”:“巴兹”, “文档计数”:1 ]

如果您检查聚合,您将看到已返回小写值。例如"key": "bar"

有没有办法改变聚合返回实际值?

例如"key": "Bar"

【问题讨论】:

【参考方案1】:

如果您想进行不区分大小写的搜索但在聚合中返回精确值,则不需要任何规范化器。您可以简单地使用带有keyword 子字段的text 字段(默认情况下将标记小写并允许不区分大小写的搜索)。您可以将前者用于搜索,而将后者用于聚合。它是这样的:

PUT index

  "mappings": 
    "_doc": 
      "properties": 
        "foo": 
          "type": "text",
          "fields": 
            "keyword": 
              "type": "keyword"
            
          
        
      
    
  

索引您的两个文档后,您可以在foo.keyword 上发出terms 聚合:

GET index/_search

  "size": 2,
  "aggs": 
    "foo_terms": 
      "terms": 
        "field": "foo.keyword"
      
    
  

结果会是这样的:


  "took": 0,
  "timed_out": false,
  "_shards": 
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  ,
  "hits": 
    "total": 2,
    "max_score": 1,
    "hits": [
      
        "_index": "index",
        "_type": "_doc",
        "_id": "2",
        "_score": 1,
        "_source": 
          "foo": "Baz"
        
      ,
      
        "_index": "index",
        "_type": "_doc",
        "_id": "1",
        "_score": 1,
        "_source": 
          "foo": "Bar"
        
      
    ]
  ,
  "aggregations": 
    "foo_terms": 
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        
          "key": "Bar",
          "doc_count": 1
        ,
        
          "key": "Baz",
          "doc_count": 1
        
      ]
    
  

【讨论】:

感谢您的回答。它是否允许精确匹配搜索,如关键字? 是的,通过搜索foo.keyword,您可以搜索精确值,在搜索foo 时,您可以不区分大小写搜索。 这非常适合我的用例,但是,除了上述两个条件(不区分大小写和聚合使用)。它还需要通配符支持,同时在聚合后仍保留原始值。映射应该如何制定? @MarcusLim 请创建一个新问题(可能引用这个问题)并解释您的其他用例。

以上是关于使用术语聚合执行搜索时如何返回实际值(不是小写字母)?的主要内容,如果未能解决你的问题,请参考以下文章

elasticsearch - 聚合返回 key 中的术语,但不是完整的字段,我怎样才能返回完整的字段?

出错处理2——包裹函数

Elasticsearch:从聚合中的存储桶访问值

Java 中无参无返回值方法的使用

通过数组中的字符串聚合 Elasticsearch 术语

如何按显示的值而不是数据字段值对gridview列进行排序/过滤