2015-10-30 4 views
0

Я получаю ошибочные результаты при выполнении агрегирования терминов в поле names в индексе. Ниже отображения я использовал в names поле:Сбой агрегации в elasticsearch

{ 
    "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 
     } 
    ] 
    } 
} 

Как вы можете видеть, У меня одинаковые имена с различными оболочками, которые показаны как разные ведра в агрегации. Что я хочу здесь, независимо от случая, имена должны быть сгруппированы вместе.

+0

Каким образом они должны быть сгруппированы? под «John Martin» или «John martin» или что-то еще, например. нижняя часть 'john martin'? –

ответ

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 
     } 
    ] 
    } 
} 
2

Есть 2 варианта здесь

  1. Используйте not_analyzed вариант - Это один имеет тот недостаток, что же строка различных случаев привычка рассматривать как на
  2. ключевое слово Tokenizer + строчной фильтр - У этого нет , выше выпуска

Я аккуратно изложил эти два подхода и ho w, чтобы использовать их здесь - https://qbox.io/blog/elasticsearch-aggregation-custom-analyzer

Смежные вопросы