упругий поиск соответствия фразу_prefix и другие

Привет, у меня есть проблема сasticsearch,
у меня есть какой-то результат, как

  • modul’ion
  • тестовый литиевый файл

Когда я делаю запрос, если я набираю ‘mod’, я не могу найти результат, я добавляю тип: «фраза_префикс» к моему запросу, и теперь я нахожу результат

modul’ion

но теперь, когда я печатаю литий, результат не находит

тестовый литиевый файл

мой запрос

    $query ['match'] ['_all'] ["query"] = strtolower ( $keyword );
$query ['match'] ['_all'] ["type"] = "phrase_prefix";
$query ['match'] ['_all'] ["analyzer"] = "synonym";

также я использую анализатор синонимов, который содержит «lithium => Rechargeable Lithium», моя проблема в том, что если анализатор не используется или я удаляю

$ query [‘match’] [‘_all’] [«type»] = «фраза_prefix»;

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

я установил анализатор с этим запросом

 {"analysis" : {
"analyzer" : {
"synonym" : {
"tokenizer" : "whitespace",
"filter" : ["synonym"]
}
},
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms_path" : "synonym.txt",
"ignore_case" : true
}
}
}
}

0

Решение

Прежде всего, я не вижу никаких проблем с вашими сопоставлениями, они прекрасно работают в бэкэнде. Ваша проблема в том, что вы запрашиваете _all поле, которое необходимо настроить отдельно. Если вы не укажете это, у него будут параметры по умолчанию, которые можно увидеть Вот. Чтобы изменить это, я использовал эти настройки и сопоставления:

PUT /test
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "whitespace",
"char_filter": ["my_mapping"],
"filter": [
"lowercase",
"my_synonym"]
}
},
"filter": {
"my_synonym": {
"type": "synonym",
"ignore_case": true,
"synonyms": [
"rechargeable lithium => lithium"]
}
},
"char_filter": {
"my_mapping": {
"type": "mapping",
"mappings": [
"'=>"]
}
}
}
},
"mappings": {
"test": {
"_all": {
"enabled": true,
"analyzer": "my_analyzer"}
}
}
}

Эти настройки разбивают ваши токены на пробелы, удаляют кавычки из токенов и строчные буквы, так что:

  • modul'ion будет проиндексирован как modulion и всякий раз, когда пользователь вводит любую из этих фраз — он найдет ее.
  • rechargeable lithium заменяется lithium как синоним.
  • Из-за lowercase фильтр, поэтому ваши поиски нечувствительны к регистру.

Используя эти сопоставления, я добавил ваши данные в индекс с помощью:

PUT /test/test/1
{
"text": "modul'ion"}

PUT /test/test/2
{
"text": "test lithium file"}

Теперь запустим этот запрос:

POST /test/test/_search
{
"query": {
"match": {
"_all": {
"query": "rechargeable lithium",
"type": "phrase_prefix"}
}
}
}

Возвращает мне этот документ:

{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.15342641,
"hits": [
{
"_index": "test",
"_type": "test",
"_id": "2",
"_score": 0.15342641,
"_source": {
"text": "test lithium file"}
}
]
}
}

Оба следующих запроса:

POST /test/test/_search
{
"query": {
"match": {
"_all": {
"query": "mod",
"type": "phrase_prefix"}
}
}
}

POST /test/test/_search
{
"query": {
"match": {
"_all": {
"query": "modulion",
"type": "phrase_prefix"}
}
}
}

Возвращает это:

{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.30685282,
"hits": [
{
"_index": "test",
"_type": "test",
"_id": "1",
"_score": 0.30685282,
"_source": {
"text": "modul'ion"}
}
]
}
}

Это всего лишь RAW JSON-запросы, но я думаю, вы сможете справиться с ними в PHP.

3

Другие решения

Проблема не в типе запроса, а в синонимах. Фильтр синонимов обычно используется для замены термина другим, а не термином на целую фразу, потому что фраза впоследствии не будет разбита на токены.

Вы должны знать, что анализ используется дважды: один раз при индексации и другой раз при поиске. Давайте предположим, что ваши документы были проанализированы с помощью стандартного анализатора (по умолчанию):

  • Ввод «modul’ion» → 1 Индексированный термин: «modul’ion»
  • Введите «тестовый литиевый файл» → 3 проиндексированных термина: «тест», «литий», «файл»

Если вы ищете с помощью стандартного анализа (без синонимов) с помощью фразы_префикс:

  • Введите «mod» → 1 Термин поиска Префикс «mod» найден в # 1
  • Введите «литий» → 1 Условие поиска Префикс «литий» найден в # 2
  • Введите «тест лития» → 2 Условие поиска Префикс «тест», «литий» найден в # 2

Если вы ищете с вашим собственным анализатором (синонимы)

  • Введите «mod» → 1 Термин поиска Префикс «mod» найден в # 1
  • Ввод «литий» → 1 Префикс поискового термина «Литий литий» не найден
  • Вход «test lithium» → 2 Префикс поискового термина «test», «Rechargeable Lithium» не найден

Вы также должны быть осторожны с регистром, если вы индексируете в нижнем регистре (цепочка анализа во время индекса содержит фильтр в нижнем регистре), не пытайтесь искать в верхнем регистре (цепочка анализа во время поиска выдает «Lithium» вместо «lithium» «).

Если вы новичок в Elasticsearch, я советую вам:

  1. Начните с тех же настроек анализа для индексации и поиска. Вы уже знаете, как настроить анализатор, вам нужно только использовать Put Mapping API к индексации конфигурации
  2. Протестируйте цепочку анализа с Анализ API

Например:

PUT the_index/_mapping/the_type
{
"properties": {
"the_field": {
"type": "string",
"analyze": "the_analyzer"}
}
}

GET the_index/_analyze?analyzer=synonym&text=modul'ion
GET the_index/_analyze?analyzer=synonym&text=test lithium
0

По вопросам рекламы [email protected]