Как объединить несколько запросов в ElasticSearch - PullRequest
0 голосов
/ 02 марта 2020

Я сталкиваюсь с проблемой, пытающейся правильно объединить эластичные c поисковые запросы, в SQL мой запрос будет выглядеть примерно так:

Select * from ABPs where (PId = 10 and PUId = 1130) or (PId = 30 and PUId = 2000) or (PlayerID = '12345')

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

Запрос A) (PId = 10 и PUId = 1130) переводится в

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "PId": "1366"
          }
        },
        {
          "term": {
            "PUId": "10"
          }
        }
      ]
    }
  }
}

Запрос B) (PId = 10 и PUId = 1130) переводится так же, как указано выше. с разными значениями

Запрос C) (PlayerID = '12345') переводится в

{
  "query": {
    "match": {
      "PlayerUuid": "62fe0832-7881-477c-88bb-9cbccdbfb3c3"
    }
  }
}

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

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Вы можете использовать Bool query , используя should (логическое ИЛИ) и must (логическое И).

Ниже приведено представление запроса ES для предложения Select * from ABPs where (PId = 10 and PUId = 1130) or (PId = 30 and PUId = 2000) or (PlayerID = '12345')

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "PId": "10"
                }
              },
              {
                "term": {
                  "PUId": {
                    "value": "1130"
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "term": {
                  "PId": "30"
                }
              },
              {
                "term": {
                  "PUId": "2000"
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "term": {
                  "PlayerId": "12345"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Обратите внимание, что я предполагаю, что поля PId, PUId и PlayerId имеют тип keyword.

0 голосов
/ 02 марта 2020

Оберните все ваши запросы в should -предложение bool -запроса, который вы поместите в filter -предложение другого bool -запроса верхнего уровня.

Псевдо- код (как я печатаю на мобильном телефоне):

“bool”: {
  “filter”: {
    “bool”: {
      “should”: [
        {query1},
        {query2},
        {query3}
      ]
    }
  }
}

В bool - запросе, состоящем только из should -классов, будет требоваться, чтобы хотя бы один из запросы в предложении should должны совпадать (minimum_should_match - будет в таком сценарии).

Обновление с фактическим запросом (дополнительное объяснение):

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "should": [
            {"bool": {{"must": [ {"term": {"PId": "10"}},{"term": {"PUId": "1130"}} ]}}},
            {"bool": {{"must": [ {"term": {"PId": "30"}},{"term": {"PUId": "2000"}} ]}}},
            {"term": {"PlayerId": "12345"}}
          ]
        }
      }
    }
  }
}

Приведенный выше пример оборачивает ваш фактический bool -запрос в filer -класс другого высокоуровневого bool -запроса, чтобы следовать передовым методикам и гарантировать лучшую производительность: всякий раз, когда вы не не заботясь о баллах, особенно когда речь идет о точных совпадениях запросов, вы должны поместить их в filter -пункты. Для этих запросов Elasticsearch будет не вычислять оценку и, следовательно, может даже потенциально кэшировать результаты этого запроса для еще большей производительности.

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