Постобработка эластичных результатов с другим поиском (миграция из Solr)

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

q  = some_field:(the brown fox)
fl = some_field, full_match:exists(query({!edismax v='some_field:(the brown fox)' mm='100%'}))

Результат Solr выглядит следующим образом:

{
    "response": {
        "docs": [
            {
                "some_field": "The Brown Bear",
                "full_match": false
            },
            {
                "some_field": "The Quick Brown Fox",
                "full_match": true
            }
        ]
    }
}

Флаг используется клиентом для дальнейшей обработки результирующих документов, независимо от оценки (которую я пропустил в примере). Я нашел это довольно разумным, поскольку токенизация и распределенная вычислительная мощность Solr используются вместо того, чтобы делать все в клиенте.

Теперь в Elastic я предполагаю, что это должно быть сделано в блоке script_fields, но на самом деле я понятия не имею, как выполнить подзапрос безболезненным скриптом, и после двух дней исследований я сомневаюсь, что это вообще возможно:

{
    "query": {
        "match": {
            "some_field": "the brown fox"
        }
    },
    "_source": [
        "some_field"
    ],
    "script_fields": {
        "full_match": {
            "script": "???" <-- Search with Painless script?
        }
    }
}

Любые творческие идеи приветствуются.


person oliver_t    schedule 17.06.2020    source источник


Ответы (1)


Как насчет использования Elasticsearch именованные запросы в сочетании с minimum_should_match и установить для него значение 100%, чтобы соответствовать только документам, в которых совпадают все токены?

Затем вы сможете обнаруживать запросы, в ответе на которые совпадают все токены. Вы также можете установить boost: 0, чтобы не влиять на оценку вашего основного запроса.

Вот пример запроса:

{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "message": {
                            "query": "the brown fox",
                            "_name": "main_query"
                        }
                    }
                },
                {
                    "match": {
                        "message": {
                            "query": "the brown fox",
                            "_name": "all_tokens_match",
                            "minimum_should_match": "100%",
                            "boost": 0
                        }
                    }
                }
            ]
        }
    }
}

Затем вы получите ответ, который выглядит примерно так:

{
    "hits": [
        {
            "_score": 0.99938476,
            "_source": {
                "message": "The Quick Brown Fox"
            },
            "matched_queries": [
                "main_query",
                "all_tokens_match"
            ]
        },
        {
            "_score": 0.38727614,
            "_source": {
                "message": "The Brown Bear"
            },
            "matched_queries": [
                "main_query"
            ]
        }
    ]
}

Документы, в которых совпадают все токены в вашем запросе, будут иметь all_tokens_match в части matched_queries ответа.

person Samir Wafa    schedule 23.06.2020
comment
Спасибо, работает как шарм! В отличие от Solr, флаг теперь вычисляется на этапе поиска, а не на этапе выборки. Но это, кажется, не большая проблема с производительностью. - person oliver_t; 24.06.2020