Elasticsearch не возвращает совпадений в единственном числе / множественном числе

#curl #elasticsearch

#curl #elasticsearch

Вопрос:

Я использую php-библиотеку elasticsearch для индексации и поиска документов на моем веб-сайте. Это код для создания индекса:

 curl -XPUT 'http://localhost:9200/test/' -d '
{
  "index": {
    "numberOfShards": 1,
    "numberOfReplicas": 1
  }
}'
  

Затем я использую curl XPUT для добавления документов в индекс и XGET для запроса индекса. Это работает хорошо, за исключением того факта, что сингулярные и множественные слова запроса не совпадают по индексу при возврате результатов. Например, когда я ищу «обсуждения», совпадения для «обсуждения» не возвращаются, и наоборот. Почему это так? Я думал, что об этом позаботились по умолчанию в elasticsearch. Есть ли что-нибудь, что мы должны упомянуть явно, чтобы оно соответствовало формам единственного / множественного числа?

Ответ №1:

Анализатор elasticsearch по умолчанию не выполняет stemming, и это то, что вам нужно для обработки множественного числа. единственное число. Вы можете попробовать использовать Snowball Analyzer для ваших текстовых полей, чтобы посмотреть, работает ли он лучше для вашего варианта использования:

 curl -XPUT 'http://localhost:9200/test' -d '{
    "settings" : {
        "index" : {
            "number_of_shards" : 1,
            "number_of_replicas" : 1
        }
    },
    "mappings" : {
        "page" : {
            "properties" : {
                "mytextfield": { "type": "string",  "analyzer": "snowball", "store": "yes"}
            }
        }
    }
}'
  

Комментарии:

1. Я попробовал это, и я получаю сообщение об ошибке: «Сообщение: Не удалось загрузить параметр класса [type] со значением [snowball]». Должен ли я устанавливать здесь что-то еще? Если да, то что и откуда?

2. Какую версию elasticsearch вы используете? Я протестировал его на 0.17 и на master, и он отлично работает на обоих с настройками по умолчанию. Вы каким-либо образом изменили команду?

3. Я использую elasticsearch 0.14. Я не изменял команду — не уверен, почему получаю ошибку. Я использовал porter stem, и у меня это сработало. Я добавил конфигурацию, которую использовал в ответе ниже. Спасибо за вашу помощь!

4. Имотов, нужна ваша помощь в одном вопросе — в приведенном вами примере вы определили поля для основы (например, mytextfield в вашем коде). Как мне указать, что вывод должен происходить во всех полях? Был бы очень признателен за вашу помощь

5. Вы можете создать анализатор с именем «default» так же, как вы создали «stem», и этот анализатор будет применяться ко всем полям по умолчанию. Или вы можете сделать это с помощью динамических шаблонов ( elasticsearch.org/guide/reference/mapping/root-object-type.html ). Это более сложный метод, но он дает вам больше гибкости. Я думаю, что эта функция уже присутствовала в версии 0.14, но я не уверен на 100%.

Ответ №2:

Почему-то snowball у меня не работает … я получаю ошибки, о которых я упоминал в комментарии к ответу @imotov. Я использовал porter stem, и у меня это отлично сработало. Это конфигурация, которую я использовал:

 curl -XPUT localhost:9200/index_name -d '
{
"settings" : {
    "analysis" : {
        "analyzer" : {
            "stem" : {
                "tokenizer" : "standard",
                "filter" : ["standard", "lowercase", "stop", "porter_stem"]
            }
        }
    }
},
"mappings" : {
    "index_type_1" : {
        "dynamic" : true,
        "properties" : {
            "field1" : {
                "type" : "string",
                "analyzer" : "stem"
            },
            "field2" : {
                "type" : "string",
                "analyzer" : "stem"
            }
         }
      }
   }
}'
  

Комментарии:

1. большое вам спасибо @ninja за то, что вы действительно ввели свое сопоставление. porter_stem — это спасение

Ответ №3:

Поскольку фильтр ‘porterStem’ сверхчувствителен, он больше подходит, если вы используете фильтр ‘minimal_english’. ‘porterStem’ создает аналогичные маркеры для таких слов, как :

поиск ‘Test’ приведет к ‘Test’, ‘Tests’, ‘Testing’, ‘Tester’ и др.

Но ‘minimal_english’ выдаст только — ‘Test’ и ‘Tests’.

Комментарии:

1. Ваш ответ не был отмечен как правильный, поскольку он появился намного позже первого, но это, очевидно, намного лучшее решение. анализатор snowball ужасно неточен. porterStem немного лучше и может быть полезен. kstem еще менее чувствителен, а minimal_english — наименее чувствительный. Но снежный ком ужасен.

2. @Sekai в вашем Java-коде minimal_english может быть импортирован из org.apache. lucene. analysis.ru.EnglishMinimalStemFilter и для использования в запросе это будет «filter: minimal_english»