Фильтр ElasticSearch, основанный на сходстве полей - PullRequest
0 голосов
/ 03 января 2019

Для справки, я использую Elasticsearch 6.4.0

У меня есть запрос Elasticsearch, который возвращает определенное количество совпадений, и я пытаюсь удалить совпадения со значениями текстового поля, которые слишком похожи.Мой запрос:

{
  "size": 10,
  "collapse": {
    "field": "author_id"
  },
  "query": {
    "function_score": {
      "boost_mode": "replace",
      "score_mode": "avg",
      "functions": [
        {
          //my custom query function
        }
      ],
      "query": {
        "bool": {
          "must_not": [
            {
              "term": {
                "author_id": MY_ID
              }
            }
          ]
        }
      }
    }
  },
   "aggs": {
    "book_name_sample": {
      "sampler": {
        "shard_size": 10
      },
      "aggs": {
        "frequent_words": {
          "significant_text": {
            "field": "book_name",
            "filter_duplicate_text": true
          }
        }
      }
    }
  }
}

В этом запросе используется оценка пользовательских функций в сочетании с фильтром для возврата книг, которые могут понравиться человеку (если они еще не созданы).Дело в том, что для некоторых людей он возвращает книги с очень похожими именами (например, «Жизнь Джорджа Вашингтона», «Хорошие времена с Джорджем Вашингтоном», «Кем был Джордж Вашингтон»), и я бы хотел, чтобы у хитов был более разнообразный набор.names.

Я использую bucket_selector для агрегирования обращений на основе сходства текста, и запрос дает мне что-то вроде:

...,
"aggregations": {
        "book_name_sample": {
            "doc_count": 10,
            "frequent_words": {
                "doc_count": 10,
                "bg_count": 482626,
                "buckets": [
                    {
                        "key": "George",
                        "doc_count": 3,
                        "score": 17.278715785140975,
                        "bg_count": 9718
                    },
                    {
                        "key": "Washington",
                        "doc_count": 3,
                        "score": 15.312204414323656,
                        "bg_count": 10919
                    }
                ]
            }
        }
    }

Можно ли отфильтровать возвращенные документы на основеэтот результат агрегации в Elasticsearch?IE удаляет хиты с book_name_sample doc_count меньше чем X?Я знаю, что могу сделать это на PHP или на любом другом языке, который использует хиты, но я бы хотел сохранить это в ES.Я попытался использовать агрегатор bucket_selector, например, так:

"book_name_bucket_filter": {
                    "bucket_selector": {
                        "buckets_path": {
                          "freqWords": "frequent_words"
                        },
                        "script": "params.freqWords < 3"
                    }
                }

Но затем я получаю сообщение об ошибке: org.elasticsearch.search.aggregations.bucket.sampler.InternalSampler cannot be cast to org.elasticsearch.search.aggregations.InternalMultiBucketAggregation

Кроме того, если этот фильтр удаляет достаточно документов, так что счетчик обращенийменьше, чем запрошенный размер, можно ли сказать ES, чтобы он выбрал следующие лучшие хиты для подсчета очков, чтобы заполнить счетчик hits?

1 Ответ

0 голосов
/ 12 января 2019

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

...