Elasticsearch Больше нравится этот запрос

Я пытаюсь понять, как больше похоже на то, что этот запрос работает, и я, кажется, что-то упускаю. Я читал документацию, но документации ES часто... не хватает.

Цель состоит в том, чтобы иметь возможность ограничивать результаты по частоте терминов, как это было сделано здесь .

Поэтому я создал простой индекс, включая векторы терминов для отладки, а затем добавил два простых документа.

DELETE /test_index

PUT /test_index
{
   "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 0
   },
   "mappings": {
      "doc": {
         "properties": {
            "text": {
               "type": "string",
               "term_vector": "yes"
            }
         }
      }
   }
}

PUT /test_index/doc/1
{
    "text": "apple, apple, apple, apple, apple"
}

PUT /test_index/doc/2
{
    "text": "apple, apple"
}

Когда я смотрю на термвекторы, я вижу то, что ожидаю:

GET /test_index/doc/1/_termvector
...
{
   "_index": "test_index",
   "_type": "doc",
   "_id": "1",
   "_version": 1,
   "found": true,
   "term_vectors": {
      "text": {
         "field_statistics": {
            "sum_doc_freq": 2,
            "doc_count": 2,
            "sum_ttf": 7
         },
         "terms": {
            "apple": {
               "term_freq": 5
            }
         }
      }
   }
}

GET /test_index/doc/2/_termvector
{
   "_index": "test_index",
   "_type": "doc",
   "_id": "2",
   "_version": 1,
   "found": true,
   "term_vectors": {
      "text": {
         "field_statistics": {
            "sum_doc_freq": 2,
            "doc_count": 2,
            "sum_ttf": 7
         },
         "terms": {
            "apple": {
               "term_freq": 2
            }
         }
      }
   }
}

Когда я запускаю следующий запрос с "min_term_freq": 1, я получаю оба документа:

POST /test_index/_search
{
   "query": {
      "more_like_this": {
         "fields": [
            "text"
         ],
         "like_text": "apple",
         "min_term_freq": 1,
         "percent_terms_to_match": 1,
         "min_doc_freq": 1
      }
   }
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 0.5816214,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_score": 0.5816214,
            "_source": {
               "text": "apple, apple, apple, apple, apple"
            }
         },
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "2",
            "_score": 0.5254995,
            "_source": {
               "text": "apple, apple"
            }
         }
      ]
   }
}

Но если я увеличу "min_term_freq" до 2 (или более), я ничего не получу, хотя я ожидаю, что оба документа будут возвращены:

POST /test_index/_search
{
   "query": {
      "more_like_this": {
         "fields": [
            "text"
         ],
         "like_text": "apple",
         "min_term_freq": 2,
         "percent_terms_to_match": 1,
         "min_doc_freq": 1
      }
   }
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 0,
      "max_score": null,
      "hits": []
   }
}

Почему? Что мне не хватает?

Если я хочу настроить запрос, который будет возвращать только документ, в котором "apple" встречается 5 раз, но не тот, в котором он встречается 2 раза, есть ли лучший способ?

Вот код, для удобства:

http://sense.qbox.io/gist/341f9f77a6bd081debdcaa9e367f5a39be9359cc


person Sloan Ahrens    schedule 03.02.2015    source источник


Ответы (2)


Минимальная частота термина и минимальная частота документа фактически применяются к входу перед выполнением MLT. Это означает, что, поскольку у вас есть только одно вхождение яблока во входном тексте, яблоко никогда не было квалифицировано для MLT, поскольку минимальная частота терминов установлена ​​​​на 2. Если вы измените свой ввод на «яблоко яблоко», как показано ниже, все будет работать -

POST /test_index/_search
{
   "query": {
      "more_like_this": {
         "fields": [
            "text"
         ],
         "like_text": "apple apple",
         "min_term_freq": 2,
         "percent_terms_to_match": 1,
         "min_doc_freq": 1
      }
   }
}

То же самое касается и минимальной частоты документов. Apple встречается по крайней мере в 2 документах, поэтому значение min_doc_freq до 2 соответствует требованиям применения из входного текста для операций MLT.

person Vineeth Mohan    schedule 04.02.2015
comment
Спасибо, Винит. Это работает, хотя я до сих пор не понимаю, почему. Если я ищу {... "like_text": "apple apple apple", "min_term_freq": 3,...}, я все равно получаю оба результата, хотя яблоко встречается менее 3 раз в одном из документов. Итак, как я могу ограничить результаты теми, в которых термин встречается с минимальной частотой или выше? - person Sloan Ahrens; 04.02.2015
comment
Я не думаю, что вы можете использовать MLT для этого. Ограничения минимальной частоты и минимальной частоты документа фактически применяются во входном тексте, а не в документе сравнения. Другим способом было бы использовать подключаемый модуль сценария для достижения этого на стороне сценария фильтра - " title="elasticsearch фильтр по количеству упоминаний"> stackoverflow.com/questions/28296320/ - person Vineeth Mohan; 04.02.2015
comment
Попался. Спасибо за помощь. - person Sloan Ahrens; 04.02.2015
comment
Я думаю, что запрос mlt не поддерживает процент_термов_к_соответствию, по крайней мере, он не работает для ES 2.2. - person isaranchuk; 28.04.2016
comment
Будет ли работать MLT в значении свойства не текст а массив чисел? Если нет, то есть ли что-то, что будет работать для этого эффекта? Мне нужно использовать теги документа и использовать их для получения других документов с наибольшим количеством совпадающих тегов (чисел) - person George Cscnt; 06.03.2020

Как автор этого вопроса, я тоже пытался обдумать запрос more_like_this...

Мне пришлось немного потрудиться, чтобы найти хорошие источники информации в Интернете, но (как и в большинстве случаев) больше всего помогает документация, поэтому вот ссылка на документацию и некоторые более важные термины (и/или немного сложнее понять, поэтому я добавил свою интерпретацию):

max_query_terms — максимальное количество условий запроса, которые будут выбраны (из каждого входного документа). Увеличение этого значения дает большую точность за счет скорости выполнения запроса. По умолчанию 25.

min_term_freq - Минимальная частота терминов, ниже которой термины во входном документе будут игнорироваться. По умолчанию 2.

Если термин встречается во входном документе менее 2 (по умолчанию) раз, он будет проигнорирован из входного документа, т.е. не будет искаться в других возможных more_like_this документах.

min_doc_freq - Минимальная частота документа, ниже которой термины во входном документе будут игнорироваться. По умолчанию 5.

Это заняло у меня секунду, так что вот моя интерпретация:

В скольких документах должен появиться термин из входного документа, чтобы его можно было выбрать в качестве термина запроса.

Вот оно, надеюсь, я спас кому-то несколько минут его жизни. :)

Ваше здоровье!

person Filip Savic    schedule 21.09.2019