Как предотвратить условия факела от токенизации

Я использую условия Facet, чтобы получить все уникальные значения и их количество для поля. И я получаю неправильные результаты.

term: web 
Count: 1191979 
term: misc 
Count: 1191979 
term: passwd 
Count: 1191979 
term: etc 
Count: 1191979 

Пока фактический результат должен быть:

term: WEB-MISC /etc/passwd 
Count: 1191979 

Вот мой пример:

{
  "facets": {
    "terms1": {
      "terms": {
        "field": "message"
      }
    }
  }
}

Ответ 1

Если переиндексирование является опцией, было бы лучше всего изменить отображение и пометить эти поля как not_analyzed

"your_field" : { "type": "string", "index" : "not_analyzed" }

Вы можете использовать тип нескольких полей, если требуется сохранить анализируемую версию поля:

"your_field" : {
  "type" : "multi_field",
    "fields" : {
      "your_field" : {"type" : "string", "index" : "analyzed"},
      "untouched" : {"type" : "string", "index" : "not_analyzed"}
  }
}

Таким образом, вы можете продолжить использование your_field в запросах при выполнении поиска фасетов с помощью your_field.untouched.

В качестве альтернативы, если это поле сохранено, вы можете вместо этого использовать фасет поля script:

"facets" : {
  "term" : {
    "terms" : {
      "script_field" : "_fields.your_field.value"
    }
  }
}

В крайнем случае, если это поле не сохраняется, но источник записи хранится в индексе, вы можете попробовать следующее:

"facets" : {
  "term" : {
    "terms" : {
      "script_field" : "_source.your_field"
    }
  }
}

Первое решение является наиболее эффективным. Последнее решение является наименее эффективным и может занимать много времени на большом индексе.

Ответ 2

Ничего себе, я также получил эту же проблему сегодня, в то время как агрегирование терминов в недавнем эластичном поиске. После поиска в Google и некоторого частичного понимания выяснилось, как работает эта geeky indexing (что очень просто).

Запросы могут найти только те термины, которые существуют в инвертированном индексе

Когда вы индексируете следующую строку

"WEB-MISC /etc/passwd"

он будет передан анализатору. Анализатор может маркировать его в

"WEB", "MISC", "etc" and "passwd" 

с информацией о позиции. И эти жетоны могут фильтроваться в нижний регистр, например

"web", "misc", "etc" and "passwd"

Итак, после индексирования поисковый запрос может видеть только выше 4. не полное слово "WEB-MISC/etc/passwd". Для вашего требования следующие варианты, которые вы можете использовать

1.Change the Default Analyzer used by elasticsearch([link][1])
2.If it is not need, just TurnOff the analyzer by setting 'not_analyzed' for the fields you need
3.To convert the already indexed data searchable, re-indexing is the only option

Ответ 3

Я кратко объяснил эту проблему и предложил два решения здесь. Здесь я говорил о нескольких подходах. Одним из них является использование not_analyzed для сохранения строки как есть. Но тогда, поскольку у него есть недостаток нечувствительности к регистру, лучшим подходом будет использование ключевого слова tokenizer + нижний регистр