Подтвердить что ты не робот

Elasticsearch "Больше похоже на этот" API против более_подобного запроса

У Elasticsearch есть две аналогичные функции для получения "похожих" документов:

Существует "Больше похоже на этот API" . Это дает мне документы, похожие на данные. Однако я не могу использовать его в более сложных выражениях.

Существует также запрос "more_like_this" для использования в API поиска. Я могу использовать его в bool или повышать выражения, но я могу" t дать ему идентификатор документа. Я должен предоставить параметр "like_text".

У меня есть документы с тегами и контентом. В некоторых документах будут хорошие теги, а у некоторых их не будет. Мне нужна функция "Подобные документы", которая будет работать каждый раз, но ранжирует документы с соответствующими тегами выше, чем документы с соответствующим текстом. Моя идея:

{
    "boosting" : {
        "positive" : {
            "more_like_this" : {
                "fields" : ["tag"],
                "id" : "23452",
                "min_term_freq" : 1
            }
        },
        "negative" : {
            "more_like_this" : {
                "fields" : ["tag"],
                "id" : "23452",
            }
        },
        "negative_boost" : 0.2
    }
}

Очевидно, это не работает, потому что в "more_like_this" нет "id". Каковы альтернативы?

4b9b3361

Ответ 1

Прежде всего, небольшое введение о более похожей на эту функциональность и то, как она работает. Идея состоит в том, что у вас есть конкретный документ, и вы хотите, чтобы некоторые другие были похожи на него.

Чтобы достичь этого, нам нужно извлечь некоторый контент из текущего документа и использовать его, чтобы сделать запрос, чтобы получить аналогичные. Мы можем извлекать содержимое из сохраненных полей lucene (или поля elasksearch _source, которое фактически является сохраненным полем в lucene) и каким-то образом анализировать его или использовать информацию, хранящуюся в векторах термина (если включена при индексировании), чтобы получить список терминов которые мы можем использовать для запроса, без необходимости повторного анализа текста. Я не уверен, пытается ли elasticsearch этот последний подход, если доступны векторы векторов.

больше похоже на этот запрос позволяет вам предоставлять текст независимо от того, откуда вы его взяли. Этот текст будет использоваться для запроса выбранных полей и возврата похожих документов. Текст не будет полностью использоваться, но будет повторно проанализирован, и будет сохраняться только максимум max_query_terms (по умолчанию 25), из терминов, которые имеют как минимум предоставленную min_term_freq (минимальная частота, по умолчанию 2) и документ частота между min_doc_freq и max_doc_freq. Есть также несколько параметров, которые могут влиять на сгенерированный запрос.

больше похож на этот api, делает еще один шаг, позволяя предоставить идентификатор документа и, опять же, список полей. Содержимое этих полей будет извлечено из этого конкретного документа и использовано для того, чтобы сделать этот запрос похожим на те же поля. Это означает, что сгенерированный больше похожий на этот запрос будет содержать текст свойства, содержащий ранее извлеченный текст, и будет выполняться в тех же самых полях. Как вы можете видеть, больше похоже на то, что api выполняет подобный запрос под капотом.

Скажем, более похожий на этот запрос дает вам больше гибкости, поскольку вы можете комбинировать его с другими запросами, и вы можете получить текст из любого источника, который вам нравится. С другой стороны, больше похожее на это api предоставляет общую функциональность, выполняющую для вас еще какую-то работу, но с некоторыми ограничениями.

В вашем случае я бы объединил пару разных, подобных этим запросам, чтобы вы могли использовать мощный запрос ellassearch query DSL, повысить запросы по-разному и так далее. Недостатком является то, что вы должны сами предоставить текст, так как вы не можете предоставить идентификатор документа для его извлечения.

Существуют разные способы достижения желаемого. Я бы использовал bool query, чтобы объединить два других, подобных этим запросам, в клаузуле и дать им другой вес. Я бы также использовал больше как этот полевой запрос, поскольку вы хотите запросить одно поле за раз.

{
    "bool" : {
        "must" : {
          {"match_all" : { }}
        },
        "should" : [
            {
              "more_like_this_field" : {
                "tags" : {
                  "like_text" : "here go the tags extracted from the current document!",
                  "boost" : 2.0
                }
              }
            },
            {
              "more_like_this_field" : {
                "content" : {
                  "like_text" : "here goes the content extracted from the current document!"
                }
              }
            }
        ],
        "minimum_number_should_match" : 1
    }
}

Таким образом, по крайней мере, одно из предложений должно соответствовать, а совпадение по тегам более важно, чем совпадение содержимого.

Ответ 2

Теперь это возможно с помощью нового синтаксиса как:

{
    "more_like_this" : {
        "fields" : ["title", "description"],
        "like" : [
        {
            "_index" : "imdb",
            "_type" : "movies",
            "_id" : "1"
        },
        {
            "_index" : "imdb",
            "_type" : "movies",
            "_id" : "2"
        }],
        "min_term_freq" : 1,
        "max_query_terms" : 12
    }
}

Смотрите здесь: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html