Нечувствительные акценты поиска Elasticsearch

Я использую эластичный поиск с Python. Я не могу найти способ сделать нечувствительный поиск с акцентами.

Например: У меня есть два слова. "Камион" и "Камион". Когда пользователь ищет «camion», я бы хотел, чтобы отображались два результата.

Создание индекса:

es = Elasticsearch([{u'host': u'127.0.0.1', u'port': b'9200'}])

es.indices.create(index='name', ignore=400)

es.index(
    index="name",
    doc_type="producto",
    id=p.pk,
    body={
        'title': p.titulo,
        'slug': p.slug,
        'summary': p.summary,
        'description': p.description,
        'image': foto,
        'price': p.price,
        'wholesale_price': p.wholesale_price,
        'reference': p.reference,
        'ean13': p.ean13,
        'rating': p.rating,
        'quantity': p.quantity,
        'discount': p.discount,
        'sales': p.sales,
        'active': p.active,
        'encilleria': p.encilleria,
        'brand': marca,
        'brand_title': marca_titulo,
        'sellos': sellos_str,
        'certificados': certificados_str,
        'attr_naturales': attr_naturales_str,
        'soluciones': soluciones_str,
        'categories': categories_str,
        'delivery': p.delivery,
        'stock': p.stock,
        'consejos': p.consejos,
        'ingredientes': p.ingredientes,
        'es_pack': p.es_pack,
        'temp': p.temp,
        'relevancia': p.relevancia,
        'descontinuado': p.descontinuado,
    }

Поиск:

    from elasticsearch import Elasticsearch
    es = Elasticsearch([{'host': '127.0.0.1', 'port': '9200'}])

    resul = es.search(
        index="name",
        body={
            "query": {
                "query_string": {
                    "query": "(title:" + search + " OR description:" + search + " OR summary:" + search + ") AND (active:true)",
                    "analyze_wildcard": False
                }
            },
            "size": "9999",
        }
    )
    print resul

Я искал в Google, Stackoverflow и elastic.co, но не нашел ничего подходящего.


person Marcos Aguayo    schedule 19.07.2016    source источник
comment
Какое сопоставление для тех полей, которые вы используете в своем запросе?   -  person Andrei Stefan    schedule 19.07.2016
comment
Вы имеете в виду в базе данных? Все струны. Должен ли я что-либо декларировать в запросе?   -  person Marcos Aguayo    schedule 19.07.2016
comment
Какая база данных? :-)   -  person Andrei Stefan    schedule 19.07.2016
comment
Извините, я новичок в резинке. Я имею в виду индекс. Я обновил вопрос со всем своим кодом. знак равно   -  person Marcos Aguayo    schedule 19.07.2016


Ответы (1)


Вам нужно изменить сопоставление тех полей, которые у вас есть в запросе. Изменение сопоставления требует переиндексации, чтобы поля анализировались по-другому и запрос работал.

По сути, вам нужно что-то вроде следующего ниже. Поле с именем text является просто примером. Вам необходимо применить те же настройки и для других полей. Обратите внимание, что я использовал здесь fields, чтобы корневое поле сохраняло исходный текст, проанализированный по умолчанию, а text.folded удалит символы с диакритическими знаками и позволит вашему запросу работать. Я также немного изменил запрос, чтобы вы искали обе версии этого поля (соответствует camion, но также и camión).

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "folding": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "test": {
      "properties": {
        "text": {
          "type": "string",
          "fields": {
            "folded": {
              "type": "string",
              "analyzer": "folding"
            }
          }
        }
      }
    }
  }
}

И запрос:

  "query": {
    "query_string": {
      "query": "\\*.folded:camion"
    }
  }

Кроме того, я настоятельно рекомендую прочитать этот раздел документации: https://www.elastic.co/guide/en/elasticsearch/guide/current/asciifolding-token-filter.html

person Andrei Stefan    schedule 19.07.2016
comment
Я видел нечто подобное. Но куда мне вставить этот код? Перед body{} в es.index()? - person Marcos Aguayo; 19.07.2016
comment
Я не знаю Питона. Извиняюсь. Этот код, который я предоставил, создает индекс с этими настройками и этим сопоставлением. Итак, существующий индекс необходимо удалить, код, который я предоставил, использовался для создания нового индекса, данные необходимо переиндексировать. - person Andrei Stefan; 19.07.2016