Запрос "Похожие документы"
Запрос "Похожие документы" находит документы, похожие на заданный набор документов. Для этого MLT выбирает набор представительных терминов из этих входных документов, формирует запрос, используя эти термины, выполняет запрос и возвращает результаты. Пользователь контролирует входные документы, способ выбора терминов и формирование запроса.
Простейший случай использования состоит в поиске документов, похожих на предоставленный текст. Здесь мы ищем все фильмы, содержащие текст, похожий на "Однажды в сказке", в полях "title" и "description", ограничивая количество выбранных терминов 12.
resp = client.search(
query={
"more_like_this": {
"fields": [
"title",
"description"
],
"like": "Once upon a time",
"min_term_freq": 1,
"max_query_terms": 12
}
},
)
print(resp) response = client.search(
body: {
query: {
more_like_this: {
fields: [
'title',
'description'
],
like: 'Once upon a time',
min_term_freq: 1,
max_query_terms: 12
}
}
}
)
puts response const response = await client.search({
query: {
more_like_this: {
fields: ["title", "description"],
like: "Once upon a time",
min_term_freq: 1,
max_query_terms: 12,
},
},
});
console.log(response); GET /_search
{
"query": {
"more_like_this" : {
"fields" : ["title", "description"],
"like" : "Once upon a time",
"min_term_freq" : 1,
"max_query_terms" : 12
}
}
} Более сложный случай использования состоит в смешении текстов с уже существующими в индексе документами. В этом случае синтаксис для указания документа аналогичен синтаксису, используемому в API множественного получения.
resp = client.search(
query={
"more_like_this": {
"fields": [
"title",
"description"
],
"like": [
{
"_index": "imdb",
"_id": "1"
},
{
"_index": "imdb",
"_id": "2"
},
"and potentially some more text here as well"
],
"min_term_freq": 1,
"max_query_terms": 12
}
},
)
print(resp) response = client.search(
body: {
query: {
more_like_this: {
fields: [
'title',
'description'
],
like: [
{
_index: 'imdb',
_id: '1'
},
{
_index: 'imdb',
_id: '2'
},
'and potentially some more text here as well'
],
min_term_freq: 1,
max_query_terms: 12
}
}
}
)
puts response const response = await client.search({
query: {
more_like_this: {
fields: ["title", "description"],
like: [
{
_index: "imdb",
_id: "1",
},
{
_index: "imdb",
_id: "2",
},
"and potentially some more text here as well",
],
min_term_freq: 1,
max_query_terms: 12,
},
},
});
console.log(response); GET /_search
{
"query": {
"more_like_this": {
"fields": [ "title", "description" ],
"like": [
{
"_index": "imdb",
"_id": "1"
},
{
"_index": "imdb",
"_id": "2"
},
"and potentially some more text here as well"
],
"min_term_freq": 1,
"max_query_terms": 12
}
}
} Наконец, пользователи могут смешивать текст, выбранный набор документов, а также предоставлять документы, необязательно присутствующие в индексе. Для предоставления документов, отсутствующих в индексе, используется синтаксис, аналогичный искусственным документам.
resp = client.search(
query={
"more_like_this": {
"fields": [
"name.first",
"name.last"
],
"like": [
{
"_index": "marvel",
"doc": {
"name": {
"first": "Ben",
"last": "Grimm"
},
"_doc": "You got no idea what I'd... what I'd give to be invisible."
}
},
{
"_index": "marvel",
"_id": "2"
}
],
"min_term_freq": 1,
"max_query_terms": 12
}
},
)
print(resp) response = client.search(
body: {
query: {
more_like_this: {
fields: [
'name.first',
'name.last'
],
like: [
{
_index: 'marvel',
doc: {
name: {
first: 'Ben',
last: 'Grimm'
},
_doc: "You got no idea what I'd... what I'd give to be invisible."
}
},
{
_index: 'marvel',
_id: '2'
}
],
min_term_freq: 1,
max_query_terms: 12
}
}
}
)
puts response const response = await client.search({
query: {
more_like_this: {
fields: ["name.first", "name.last"],
like: [
{
_index: "marvel",
doc: {
name: {
first: "Ben",
last: "Grimm",
},
_doc: "You got no idea what I'd... what I'd give to be invisible.",
},
},
{
_index: "marvel",
_id: "2",
},
],
min_term_freq: 1,
max_query_terms: 12,
},
},
});
console.log(response); GET /_search
{
"query": {
"more_like_this": {
"fields": [ "name.first", "name.last" ],
"like": [
{
"_index": "marvel",
"doc": {
"name": {
"first": "Ben",
"last": "Grimm"
},
"_doc": "You got no idea what I'd... what I'd give to be invisible."
}
},
{
"_index": "marvel",
"_id": "2"
}
],
"min_term_freq": 1,
"max_query_terms": 12
}
}
} Как это работает
Предположим, мы хотим найти все документы, похожие на заданный входной документ. Очевидно, что сам входной документ должен быть лучшим совпадением для этого типа запроса. Причина в основном, согласно формуле оценки Lucene, связана с терминами с наибольшим tf-idf. Поэтому термины входного документа с наивысшим tf-idf являются хорошими представителями этого документа и могут быть использованы в дизъюнктивном запросе (или OR), чтобы получить похожие документы. Запрос MLT просто извлекает текст из входного документа, анализирует его, обычно с использованием того же анализатора, что и в поле, затем выбирает лучшие K терминов с наибольшим tf-idf для формирования дизъюнктивного запроса из этих терминов.
Поля, на которых должен быть выполнен MLT, должны быть индексированы и иметь тип text или keyword. Кроме того, при использовании like с документами, либо _source должен быть включен, либо поля должны быть stored или хранить term_vector. Для ускорения анализа может помочь хранение векторов терминов во время индексирования.
Например, если мы хотим выполнить MLT на полях "title" и "tags.raw", мы можем явно хранить их term_vector во время индексирования. Мы все еще можем выполнять MLT на полях "description" и "tags", поскольку _source включен по умолчанию, но для этих полей не будет ускорения анализа.
resp = client.indices.create(
index="imdb",
mappings={
"properties": {
"title": {
"type": "text",
"term_vector": "yes"
},
"description": {
"type": "text"
},
"tags": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keyword",
"term_vector": "yes"
}
}
}
}
},
)
print(resp) response = client.indices.create(
index: 'imdb',
body: {
mappings: {
properties: {
title: {
type: 'text',
term_vector: 'yes'
},
description: {
type: 'text'
},
tags: {
type: 'text',
fields: {
raw: {
type: 'text',
analyzer: 'keyword',
term_vector: 'yes'
}
}
}
}
}
}
)
puts response const response = await client.indices.create({
index: "imdb",
mappings: {
properties: {
title: {
type: "text",
term_vector: "yes",
},
description: {
type: "text",
},
tags: {
type: "text",
fields: {
raw: {
type: "text",
analyzer: "keyword",
term_vector: "yes",
},
},
},
},
},
});
console.log(response); PUT /imdb
{
"mappings": {
"properties": {
"title": {
"type": "text",
"term_vector": "yes"
},
"description": {
"type": "text"
},
"tags": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"analyzer": "keyword",
"term_vector": "yes"
}
}
}
}
}
} Параметры
Единственный обязательный параметр - like, все остальные параметры имеют разумные значения по умолчанию. Есть три типа параметров: один для указания входного документа, другой для выбора терминов и формирования запроса.
Параметры входного документа
| | Единственный обязательный параметр запроса MLT - |
| | Параметр |
| | Список полей для извлечения и анализа текста. По умолчанию соответствует настройке индекса |
Параметры выбора терминов
| | Максимальное количество терминов запроса, которые будут выбраны. Увеличение этого значения повышает точность за счет скорости выполнения запроса. По умолчанию значение |
| | Минимальная частота встречаемости термина, ниже которой термины будут игнорироваться из входного документа. По умолчанию |
| | Минимальная частота документа, ниже которой термины будут игнорироваться из входного документа. По умолчанию |
| | Максимальная частота документа, выше которой термины будут игнорироваться из входного документа. Это может быть полезно для игнорирования часто встречающихся слов, таких как стоп-слова. По умолчанию неограничено ( |
| | Минимальная длина слова, ниже которой термины будут игнорироваться. По умолчанию |
| | Максимальная длина слова, выше которой термины будут игнорироваться. По умолчанию неограничено ( |
| | Массив стоп-слов. Любое слово из этого набора считается «неинтересным» и игнорируется. Если анализатор позволяет стоп-слова, вы можете указать MLT на их явное игнорирование, поскольку для целей сходства документов представляется разумным предположить, что «стоп-слово никогда не является интересным». |
| | Анализатор, используемый для анализа свободного текста. По умолчанию анализатор, связанный с первым полем в |
Параметры формирования запроса
| | После формирования дизъюнктивного запроса этот параметр управляет количеством терминов, которые должны совпадать. Синтаксис аналогичен параметру minimum should match. (По умолчанию |
| | Управляет тем, должен ли запрос завершиться ошибкой (бросить исключение), если какое-либо из указанных полей не соответствует поддерживаемым типам ( |
| | Каждый термин в сформированном запросе может быть дополнительно усилен его tf-idf значением. Это устанавливает коэффициент усиления для использования при использовании этой функции. По умолчанию отключено ( |
| | Указывает, должны ли входные документы также включаться в результаты поиска. По умолчанию |
| | Устанавливает значение усиления всего запроса. По умолчанию |
Альтернатива
Чтобы получить больший контроль над построением запроса к похожим документам, стоит рассмотреть написание пользовательского кода клиента для сборки выбранных терминов из примера документа в булевый запрос с желаемыми настройками. Логика в more_like_this, которая выбирает «интересные» слова из текста, также доступна через API векторов терминов. Например, используя API векторов терминов, можно предоставить пользователям выбор ключевых слов по теме, найденных в тексте документа, позволяя им выбирать интересующие слова для углубленного поиска, а не используя более «черный ящик» подход сопоставления, используемый more_like_this.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/query-dsl-mlt-query.html