Подтвердить что ты не робот

Получение граней ElasticSearch для обработки многословного содержимого поля как атомного термина

Я использую ElasticSearch и задаюсь вопросом, могу ли я использовать огранку, чтобы получить некоторые статистические данные о моих результатах, точнее, о самых упомянутых в моих результатах. У меня уже есть поле, содержащее эту информацию. Но прямо сейчас, мои результаты фасета разбивают данные в этом поле на время, когда я хотел бы сгруппировать его несколькими словами.

Т.е.: если пользователь ищет Джона, я хотел бы получить такие данные, как

   {
    [...]
    "facets" : {

        "topPeople" : {
        "_type" : "terms",
        "missing" : 0,
        "total" : 1739884,
        "other" : 1705319,
        "terms" : [ {
           "term" : "John Smith",
           "count" : 13954
          }, {
           "term" : "John Snow",
           "count" : 1432
          }, {
           "term" : "John Baird",
           "count" : 770
          }]
       }
   }

Вместо этого ElasticSearch ломает результаты по срокам и возвращает что-то вроде этого:

   {
    [...]
    "facets" : {

        "topPeople" : {
        "_type" : "terms",
        "missing" : 0,
        "total" : 1739884,
        "other" : 1705319,
        "terms" : [ {
           "term" : "John",
           "count" : 1739884
          }, {
           "term" : "Smith",
           "count" : 13954
          }, {
           "term" : "Snow",
           "count" : 1432
          }]
       }
   }

Я где-то читал, что если я не буду анализировать индекс, ElasticSearch должен вернуть полную строку слов. Тем не менее, я все еще хочу, чтобы пользователь мог выполнять поиск в поле. Я бы хотел избежать дублирования поля, чтобы он не был проанализирован. Есть ли способ получить группировку в поле с помощью ElasticSearch?

В настоящее время я использую следующий фасетный запрос:

{
 "query" : {
   [...]
 },
 "facets" : {
   "topPeople" : {
     "terms" : {
        "field" : "people",
        "size" : 3
      }
    }
  }
}
4b9b3361

Ответ 1

Ты на правильном пути. Вам нужен индекс, который не анализируется, чтобы делать то, что вы просите, но вам не нужно жертвовать тем, как пользователь ищет в поле. Ответ здесь (для версий < 1.x) - это Тип нескольких полей. Для вашего примера вы хотите, чтобы ваше сопоставление выглядело примерно так:

    "topPeople" : {
        "type" : "multi_field",
        "fields" : {
            "topPeople" : {"type" : "string", "index" : "analyzed"},
            "raw" : {"type" : "string", "index" : "not_analyzed"}
        }
    }

При поиске вы можете продолжить поиск по topPeople, но когда вы окажетесь на грани, вы окажетесь на topPeople.raw.