弹性搜索中的聚合破碎

时间:2015-10-30 03:43:03

标签: elasticsearch

我在索引中的字段names中执行术语聚合时收到了错误的结果。 以下是我用于names字段的映射:

{
  "dbnames": {
    "properties": {
      "names": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}

以下是我在字段上进行简单terms聚合的结果:

"aggregations": {
  "names": {
    "doc_count_error_upper_bound": 0,
    "sum_other_doc_count": 0,
    "buckets": [
      {
        "key": "John Martin",
        "doc_count": 1
      },
      {
        "key": "John martin",
        "doc_count": 1
      },
      {
        "key": " Victor Moses",
        "doc_count": 1
      }
    ]
  }
}

如您所见,我有相同的名称,不同的套管在聚合中显示为不同的桶。在这里我想要的是无论如何,这些名字应该在一起。

2 个答案:

答案 0 :(得分:2)

最简单的方法是确保在索引时正确设置names字段的值。

如果这不是一个选项,另一种方法是定义一个分析器,它将为您完成,并将该分析器设置为index_analyzer字段names。这样的自定义分析器需要使用keyword tokenizer(即将字段的整个值作为单个标记)和lowercase token filter(即小写值)

curl -XPUT localhost:9200/your_index -d '{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "casing": {               <--- custom casing analyzer
            "filter": [
              "lowercase"
            ],
            "tokenizer": "keyword"
          }
        }
      }
    }
  },
  "mappings": {
    "your_type": {
      "properties": {
        "names": {
          "type": "string",
          "index_analyzer": "casing"      <--- use your custom analyzer
        }
      }
    }
  }
}'

然后我们可以索引一些数据:

curl -XPOST localhost:9200/your_index/your_type/_bulk -d '
{"index":{}}
{"names": "John Martin"}
{"index":{}}
{"names": "John martin"}
{"index":{}}
{"names": "Victor Moses"}
'

最后terms字段上的names聚合将返回您预期的结果:

curl -XPOST localhost:9200/your_index/your_type/_search-d '{
  "size": 0,
  "aggs": {
    "dbnames": {
      "terms": {
        "field": "names"
      }
    }
  }
}'

结果:

{
  "dbnames": {
    "doc_count_error_upper_bound": 0,
    "sum_other_doc_count": 0,
    "buckets": [
      {
        "key": "john martin",
        "doc_count": 2
      },
      {
        "key": "victor moses",
        "doc_count": 1
      }
    ]
  }
}

答案 1 :(得分:2)

这里有2个选项

  1. 使用not_analyzed选项 - 这个选项有一个缺点 不同情况下的字符串不会被视为
  2. keyword tokenizer + lowercase filter - 这个没有 上述问题
  3. 我已经巧妙地概述了这两种方法以及如何在这里使用它们 - https://qbox.io/blog/elasticsearch-aggregation-custom-analyzer