эластичный поиск: как завершить мульти-поисковый запрос, как только мы получим желаемый результат - PullRequest
0 голосов
/ 04 июля 2018

У нас есть эластичный поисковый документ со строковым полем с именем «Тип». Это поле может иметь разные значения от «A» до «Z». Несколько документов могут иметь один и тот же тип, то есть несколько документов могут иметь тип «A»

Мы хотим написать эластичный поисковый запрос, который возвращает нам максимум 30 из этих документов. Мы хотим, чтобы вывод находился в другой группе в зависимости от типа. Например:

  1. Если у нас есть 10 документов типа A, 15 типов B, 20 типов C, я должен получить все 10 с типом A, все 15 с типом B и 5 типа C.
  2. Если у нас есть 0 документов типа A, 10 типа B, 15 типа C, 20 типа D, я должен получить все 10 с типом B, 15 типа C и 5 типа D.
  3. В худшем случае: если у нас нет документов типа A ... Y и 30 документов типа Z, я должен получить 30 документов типа Z.

Я написал для этого очень простой многопользовательский запрос (всего 26 запросов), т.е.

    POST _msearch/
    {"index":"<index_name>","type":"<type>"}
    {"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["A"]}}]}}}
    {"index":"<index_name>","type":"<type>"}
    {"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["B"]}}]}}}
    ...
    {"index":"<index_name>","type":"<type>"}
    {"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["Z"]}}]}}}

Я обеспокоен выполнением запросов с несколькими поисковыми запросами, т. Е. Для случая 1 и случая 2 мы получили достаточный вывод, т. Е. 30 документов из первых нескольких запросов, тогда почему мы должны выполнять остальные запросы с несколькими поисковыми запросами? Есть ли способ остановить операцию запроса с несколькими запросами, как только мы получим желаемое количество результатов, то есть завершить поиск с несколькими результатами, как только мы получим 30 или более результатов.

Обратите внимание:

  1. Я привел здесь очень простое условие, то есть условие различного мульти-поиска более сложное, чем просто на основе типа.
  2. Мы хотим, чтобы на выходе было несколько коллекций, т.е. типа A, типа B и т. Д., Все в разных коллекциях. (из-за этого ограничения нам пришлось исключить безболезненный вариант скрипта)

1 Ответ

0 голосов
/ 06 июля 2018

Похоже, что вы можете достичь того, что вы хотите, с помощью одного поиска с size и sort, а также опционально с помощью bool объединить запросы в один.

Могу ли я досрочно завершить многопользовательский запрос?

Нет. Из документации Multi Search мы можем сделать вывод. Он выполняет несколько поисковых запросов с определенным уровнем параллелизма и отправляет результат только после завершения всех запросов.

Это очень похоже на Bulk API , способ легко выполнять параллельные запросы.

Могу ли я получить соответствующие документы, но в пользовательском порядке?

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

POST /<index_name>/<index_type>/_search?sort=type:asc&size=30

Могу ли я сделать один поисковый запрос по нескольким индексам и при этом использовать sort?

Да, вам просто нужно определить список индексов:

POST /multisearch1,mutlisearch2/<index_type>/_search?sort=type:asc&size=30

Или подстановочное выражение:

POST /multisearch*/<index_type>/_search?sort=type:asc&size=30

Можно ли выполнить сортировку в произвольном порядке?

Да, например, с использованием Сортировка на основе сценариев . Например, если вы хотите видеть type в ваших результатах в следующем порядке: X, C, A, вы можете написать такой скрипт:

POST /<index_name>/<type>/_search
{
  "size": 30,
  "sort": {
    "_script": {
      "type": "number",
      "script": {
        "lang": "painless",
        "source": """
int r = 1;
if(doc['type'].value  == 'X') { 
  r = 100;
} else if(doc['type'].value  == 'C') { 
  r = 10;
} else if(doc['type'].value  == 'A') { 
  r = 5;
}
  r;
"""
      },
      "order": "desc"
    }
  }
}

Это также будет работать с несколькими коллекциями (как запрос выше).

Могу ли я сделать это, если у меня сложный запрос, который зависит от значения type?

Да, нет проблем, используйте bool запрос, например:

POST /<index_name>/<type>/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "type": "A"
                }
              },
              {
                "match": {
                  "description": "Quick fox"
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "term": {
                  "type": "X"
                }
              },
              {
                "match": {
                  "description": "Quick bear"
                }
              }
            ]
          }
        }
      ]
    }
  },
  "size": 30,
  "sort": {
    "_script": {
      "type": "number",
      "script": {
        "lang": "painless",
        "source": """
int r = 1;
if(doc['type'].value  == 'X') { 
  r = 100;
} else if(doc['type'].value  == 'C') { 
  r = 10;
} else if(doc['type'].value  == 'A') { 
  r = 5;
}
  r;
"""
      },
      "order": "desc"
    }
  }
}

Надеюсь, это поможет!

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