Упругий поиск - есть ли способ заставить документы в результатах, которые могут соответствовать критериям "must_not"? - PullRequest
0 голосов
/ 25 октября 2019

Мы запускаем очень большой набор данных статей. Мы выполняем поиск по определенному ключевому слову, фильтрам, диапазонам и т. Д. Наши запросы содержат структуру MUST/SHOULD/MUST_NOT/FILTER.

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

Есть ли способ ввести идентификаторы документов в запрос, которые превзойдут / переопределят предложения MUST_NOT? Или MUST_NOT король в Elastic Search независимо от этого.

Мы пробовали вложенные запросы bool в каждом MUST/SHOULD, чтобы принудительно ввести идентификатор документа в результаты, но ничего. В приведенном ниже примере он есть в блоке SHOULD.

Мы попытались принудительно вставить идентификатор документа в блок MUST, без дополнительной фразы_поставки и т. Д., Но критерий MUST_NOT по-прежнему превосходит MUST и результаты не возвращаются.

Вот пример запроса. Для простоты я удалил агрегаты.

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "must": [],
            "should": [
              {
                "multi_match": {
                  "query": "Italy",
                  "fields": [
                    "title",
                    "content^2",
                    "tags"
                  ],
                  "analyzer": "standard",
                  "boost": 1
                }
              },
              {
                "query_string": {
                  "fields": [
                    "tags"
                  ],
                  "query": "*Italy*",
                  "default_operator": "AND",
                  "minimum_should_match": 1
                }
              }
            ]
          }
        }
      ],
      "should": [
        {
          "multi_match": {
            "query": "Serie A",
            "fields": [
              "title",
              "content^2",
              "tags"
            ],
            "type": "phrase",
            "boost": 4
          }
        },
        {
          "multi_match": {
            "query": "football",
            "fields": [
              "title",
              "content^2",
              "tags"
            ],
            "boost": 3
          }
        },
        {
          "terms": {
            "_id": [
              "5.4416039680717e+23"
            ]
          }
        }
      ],
      "must_not": [
        {
          "match_phrase": {
            "content": "Cristiano Ronaldo"
          }
        },
        {
          "match": {
            "source.feed.editorialTopics": "AmericanFootball"
          }
        }
      ],
      "minimum_should_match": 1,
      "boost": 1
    }
  },
  "from": 0,
  "size": 20
}

В этом случае мы ищем документы, которые ссылаются на итальянскую серию A, но исключают все документы, содержащие Cristiano Ronaldo в содержании, за исключением одного идентификатора документа: 5.4416039680717e+23, который должен быть включен, даже если он содержит Cristiano Ronaldo в содержании.

Результат не возвращает этот идентификатор документа.

Что мы делаем не так? Или нет способа сделать это в Elastic Search?

Ответы [ 2 ]

1 голос
/ 25 октября 2019

Самый простой способ, чтобы не мешать вашей текущей логике запроса, - обернуть все с помощью выражения must. Примерно так:

{
  "query": {
    "bool": {
      "should": [
        { // --> your current query
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "multi_match": {
                        "query": "Italy",
                        "fields": [
                          "title",
                          "content^2",
                          "tags"
                        ],
                        "analyzer": "standard",
                        "boost": 1
                      }
                    },
                    {
                      "query_string": {
                        "fields": [
                          "tags"
                        ],
                        "query": "*Italy*",
                        "default_operator": "AND",
                        "minimum_should_match": 1
                      }
                    }
                  ]
                }
              }
            ],
            "should": [
              {
                "multi_match": {
                  "query": "Serie A",
                  "fields": [
                    "title",
                    "content^2",
                    "tags"
                  ],
                  "type": "phrase",
                  "boost": 4
                }
              },
              {
                "multi_match": {
                  "query": "football",
                  "fields": [
                    "title",
                    "content^2",
                    "tags"
                  ],
                  "boost": 3
                }
              },
              {
                "terms": {
                  "_id": [
                    "5.4416039680717e+23"
                  ]
                }
              }
            ],
            "must_not": [
              {
                "match_phrase": {
                  "content": "Cristiano Ronaldo"
                }
              },
              {
                "match": {
                  "source.feed.editorialTopics": "AmericanFootball"
                }
              }
            ],
            "minimum_should_match": 1,
            "boost": 1
          }
        },
        { // --> the extra logic (else)
          "must": {
            "match_phrase": {
              "content": "Cristiano Ronaldo"
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 20
}

В основном, если у вас есть запрос, полный логики, и вы хотите сказать: bring me the results that match either this big query or this smaller one. Минимальное совпадение по умолчанию равно 1, когда ничего больше (must, must_not) не присутствует.

0 голосов
/ 25 октября 2019

Я полагаю, что вы можете сделать это, поместив свой must_not и ваш запрос ID в условие must с помощьюimum_should_match 1:

"should": [
    {
        "must_not": [
            {
                "match_phrase": {
                    "content": "Cristiano Ronaldo"
                }
            },
            {
                "match": {
                    "source.feed.editorialTopics": "AmericanFootball"
                }
            }
        ]
    },
    {
        "terms": {
            "_id": [
                "5.4416039680717e+23"
            ]
        }
    },
],
"minimum_should_match": 1,

Это означает, что если вы совпадете с любым из них, ваш документ вернется. Возможно, вам придется немного подергивать это, чтобы не мешать другому предложению must (например, с помощью вложенного запроса bool?), Но принцип должен работать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...