Строка запроса elasticsearch не выполняет нечеткий запрос, как ожидалось, при использовании фраз

я не получаю ожидаемого результата при использовании фразы в query_string для elasticsearch.

скажем, у меня есть титул «Джон Уэйн едет на Манхэттен». я проиндексировал поле заголовка с помощью «стандартного» анализатора, и вот мой запрос. с нечетким индикатором (~) или без него он ничего не найдет, если я не напишу правильно «Джон Уэйн». нет результатов для 'john wane' или подобных.

"query": {

  "query_string": {
    "fields": ["title^2"],
    "query": "\"john wayne\"~1",
    "default_operator": "AND", 
    "phrase_slop": 0, 
    "minimum_should_match": "100%"
  }
}

я пытался изменить число после тильды, чтобы увеличить нечеткость, но все еще нет совпадений.

Любые идеи?


person bigerock    schedule 20.06.2014    source источник


Ответы (1)


Выполнение нечеткого поиска по фразе на самом деле является поиском по «близости». Вместо измерения расстояния Левенштейна между буквами близость между терминами в запросе.

Ваш запрос должен возвращать результаты, если это:

"query" : "john wane~1" 

Подробнее о различиях см. здесь: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#_fuzziness

Редактировать:

Вот конкретный пример отдыха:

Создайте несколько документов

curl -XPUT "http://localhost:9200/test/test/1" -d'
{
    "message" : "My best friend is John Wayne, who is yours?"
}'

curl -XPUT "http://localhost:9200/test/test/2" -d'
{
    "message" : "My best friend is John Marion Wayne, who is yours?"
}'

curl -XPUT "http://localhost:9200/test/test/3" -d'
{
    "message" : "My best friend is John Marion Mitchell Wayne, who is yours?"
}'

Пример наивного запроса, не фраза:

curl -XGET "http://localhost:9200/_search" -d'
{
    "query" : {
        "query_string": {
           "query": "john AND wane~1"
        }
    }
}'

Как сделать фразовый запрос с span. Обратите внимание, что термины написаны в нижнем регистре, поскольку термин запрос не анализируется. Кроме того, вы можете отрегулировать наклон диапазона, чтобы контролировать, насколько близко друг к другу должен быть каждый член.

curl -XGET "http://localhost:9200/_search" -d'
{
    "query" : {
        "span_near" : {
        "clauses" : [
            { "span_term" : { "message" : "john" } },
            { "span_term" : { "message" : "wayne" } }
        ],
        "slop" : 0,
        "in_order" : true
        }
    }
}'

А теперь вот реальная сделка именно то, что вы ищете.

curl -XGET "http://localhost:9200/_search" -d'
{
    "query" : {
        "span_near" : {
            "clauses" : [
                {
                    "span_multi" : {
                        "match" : {
                            "fuzzy" : {
                                "message" : {
                                    "value" : "john",
                                    "fuzziness" : "1"
                                }
                            }
                        }
                    }
                },
                {
                    "span_multi" : {
                        "match" : {
                            "fuzzy" : {
                                "message" : {
                                    "value" : "wane",
                                    "fuzziness" : "1"
                                }
                            }
                        }
                    }
                }
            ],
            "slop" : 0,
            "in_order" : true
        }
    }
}'
person ppearcy    schedule 21.06.2014
comment
не делает ли это в данном случае просто «убыль» той, которая нечеткая? вам придется сделать john~1 wane~1, но тогда вы также получите варианты 'john', которые могут быть или не быть желательными. то, что я ищу, это то, что вся фраза «джон уэйн» нечеткая, но также и то, что это фраза, и она не находит «джон» в одном документе и «уэйн» в другом. - person bigerock; 22.06.2014
comment
Да, это так. Я просто хотел показать пример запроса, который будет выполнять нечеткий поиск по определенному термину. Если вы хотите, чтобы вся фраза была нечеткой для каждого термина, все усложняется. Если вы рассматриваете свое поле как одиночный токен, вы можете выполнять нечеткие запросы к нему, но это будет на уровне всего поля. Я думаю, что вам лучше всего будет: elasticsearch.org/guide/en/elasticsearch/reference/current/ - person ppearcy; 24.06.2014
comment
я не уверен, что делает этот запрос. документация ограничена, имхо. кажется, я просто говорю, что могу обернуть совпадения в span_multi ... хорошо, но что это делает? - person bigerock; 24.06.2014
comment
Да, я понимаю ваше замешательство. В документах elasticsearch, мягко говоря, отсутствует контекст. Обновлено выше с полным примером. - person ppearcy; 25.06.2014
comment
большое спасибо за полный пример! вы упомянули, что они не были проанализированы ... так что бы вы предложили использовать в качестве анализатора, если бы вы его использовали? - person bigerock; 25.06.2014
comment
У вас есть два варианта: использовать простой анализатор и убедиться, что ваши термины вводятся в нижнем регистре в предварительном запросе, или запустить текст запроса через API анализа, чтобы получить сгенерированные термины и запрос на их основе. Однако было бы неплохо, если бы запрос span поддерживал анализ. - person ppearcy; 25.06.2014