Elasticsearch поддерживает как чувствительный, так и нечувствительный к регистру

Настройка: Elasticsearch 6.3

У меня есть индекс, который представляет каталог продуктов.

Каждый документ содержит данные об одном продукте.

Одно из полей называется categories, которое представляет собой массив строк — список соответствующих категорий.

99,9% запросов: дайте мне продукты, соответствующие категориям A, B и C. Запрос about нечувствителен к регистру, поэтому сопоставление категорий выглядит так:

"categories": {
    "type": "keyword",
    "normalizer": "lowercase_normalizer"
}

Для отчета (0,1% всех запросов) мне нужно вернуть список всех возможных категорий с учетом регистра!

Рассмотрим следующие документы:

"_id": "product1",
"_source": {
    "categories": [
        "WOMEN",
        "Footwear"
     ]
}

"_id": "product2",
"_source": {
    "categories": [
        "Men",
        "Footwear"
     ]
}

Выполнение следующего запроса:

{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": {
        "field": "categories",
        "size": 100
      }
    }
  }
}

возврат:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 40453,
    "max_score": 0,
    "hits": [

    ]
  },
  "aggregations": { 
    "sterms#categories": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 12453,
      "buckets": [
        {
          "key": "men",
          "doc_count": 27049
        },
        {
          "key": "women",
          "doc_count": 21332
        },
       .........
      ]
    }
  }
}

Есть ли способ вернуть категории с их чувствительностью к регистру (как они хранятся в документах)? Меня интересует ["WOMEN", "Men"] в результате этого запроса.

Вопрос на форуме обсуждения Elasticsearch

Спасибо, Итай.


person ItayB    schedule 20.01.2020    source источник


Ответы (1)


вам нужно настроить поле в вашем свойстве, которое не будет использовать нормализатор:

Документация по полям

Что-то вроде

"categories": {
    "type": "keyword",
    "normalizer": "lowercase_normalizer",
    "fields": {
        "case_sensitive": {
            "type": "keyword"
        }
    }
}

Затем сделайте свою агрегацию в этом поле:

{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": {
        "field": "categories.case_sensitive",
        "size": 100
      }
    }
  }
}
person Pierre Mallet    schedule 20.01.2020
comment
Я проверю это, спасибо! повлияет ли это на другие мои запросы? (не агрегация, фильтрация/термин/обязательные запросы) - person ItayB; 20.01.2020
comment
Никаких побочных эффектов :), так как ваш существующий запрос будет нацелен на то же поле, что и раньше. - person Pierre Mallet; 20.01.2020
comment
Я пытаюсь решить это сейчас. Это должно стоить мне дороже? с точки зрения оперативной памяти/памяти? - person ItayB; 31.08.2020