Привет, у меня есть проблема с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
}
}
}
}
Прежде всего, я не вижу никаких проблем с вашими сопоставлениями, они прекрасно работают в бэкэнде. Ваша проблема в том, что вы запрашиваете _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.
Проблема не в типе запроса, а в синонимах. Фильтр синонимов обычно используется для замены термина другим, а не термином на целую фразу, потому что фраза впоследствии не будет разбита на токены.
Вы должны знать, что анализ используется дважды: один раз при индексации и другой раз при поиске. Давайте предположим, что ваши документы были проанализированы с помощью стандартного анализатора (по умолчанию):
Если вы ищете с помощью стандартного анализа (без синонимов) с помощью фразы_префикс:
Если вы ищете с вашим собственным анализатором (синонимы)
Вы также должны быть осторожны с регистром, если вы индексируете в нижнем регистре (цепочка анализа во время индекса содержит фильтр в нижнем регистре), не пытайтесь искать в верхнем регистре (цепочка анализа во время поиска выдает «Lithium» вместо «lithium» «).
Если вы новичок в Elasticsearch, я советую вам:
Например:
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