Spec-Zone.ru › Elasticsearch 7
›Руководство по Elasticsearch [7.17]

Поиск данных

Запрос поиска, или запрос, — это запрос информации о данных в потоках данных или индексах Elasticsearch.

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

  • Какие процессы на моём сервере отвечают медленнее, чем за 500 миллисекунд?
  • Какие пользователи в моей сети выполняли regsvr32.exe в течение последней недели?
  • Какие страницы на моём сайте содержат определённое слово или фразу?

Поиск состоит из одного или нескольких запросов, которые объединяются и отправляются в Elasticsearch. Документы, соответствующие запросам поиска, возвращаются в попаданиях, или результатах поиска, ответа.

Поиск может также содержать дополнительную информацию, используемую для лучшей обработки его запросов. Например, поиск может быть ограничен определённым индексом или возвращать только определённое количество результатов.

Выполнить поиск

Вы можете использовать API поиска, чтобы искать и агрегировать данные, хранящиеся в потоках данных или индексах Elasticsearch. Параметр запроса тела API query принимает запросы, написанные на языке Query DSL.

Следующий запрос ищет my-index-000001, используя match запрос. Этот запрос сопоставляет документы со значением user.id равным kimchy.

GET /my-index-000001/_search
{
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  }
}

Ответ API возвращает 10 лучших документов, соответствующих запросу, в свойстве hits.hits.

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.3862942,
    "hits": [
      {
        "_index": "my-index-000001",
        "_type": "_doc",
        "_id": "kxWFcnMByiguvud1Z8vC",
        "_score": 1.3862942,
        "_source": {
          "@timestamp": "2099-11-15T14:12:12",
          "http": {
            "request": {
              "method": "get"
            },
            "response": {
              "bytes": 1070000,
              "status_code": 200
            },
            "version": "1.1"
          },
          "message": "GET /search HTTP/1.1 200 1070000",
          "source": {
            "ip": "127.0.0.1"
          },
          "user": {
            "id": "kimchy"
          }
        }
      }
    ]
  }
}

Определить поля, существующие только в запросе

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

Например, следующий запрос определяет поле runtime под названием day_of_week. Включённый скрипт вычисляет день недели на основе значения поля @timestamp и использует emit для возвращения вычисленного значения.

Запрос также включает агрегацию terms, которая работает с day_of_week.

GET /my-index-000001/_search
{
  "runtime_mappings": {
    "day_of_week": {
      "type": "keyword",
      "script": {
        "source":
        """emit(doc['@timestamp'].value.dayOfWeekEnum
        .getDisplayName(TextStyle.FULL, Locale.ENGLISH))"""
      }
    }
  },
  "aggs": {
    "day_of_week": {
      "terms": {
        "field": "day_of_week"
      }
    }
  }
}

Ответ включает агрегацию на основе поля runtime day_of_week. Под buckets находится key со значением Sunday. Запрос динамически вычислил это значение на основе скрипта, определённого в поле runtime day_of_week, никогда не индексируя поле.

{
  ...
  ***
  "aggregations" : {
    "day_of_week" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "Sunday",
          "doc_count" : 5
        }
      ]
    }
  }
}

Общие параметры поиска

Вы можете использовать следующие параметры для настройки своих поисков.

Query DSL
Query DSL поддерживает различные типы запросов, которые вы можете комбинировать, чтобы получить желаемые результаты. Типы запросов включают:

  • Булевы и другие составные запросы, которые позволяют объединять запросы и соответствия результатов на основе нескольких критериев
  • Запросы на уровне терминов для фильтрации и поиска точных совпадений
  • Запросы на полный текст, которые обычно используются в поисковых системах
  • Гео и пространственные запросы

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

  • Каково среднее время отклика моих серверов?
  • Какие IP-адреса наиболее часто посещают пользователи в моей сети?
  • Какой общий доход от транзакций по клиентам?

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

Управление страницей результатов поиска
По умолчанию поиски возвращают только 10 совпадений. Чтобы получить больше или меньше документов, см. Управление страницей результатов поиска.

Получение выбранных полей
Свойство hit.hits ответа поиска включает полное содержимое документа _source для каждого попадания. Чтобы получить только подмножество _source или других полей, см. Получение выбранных полей.

Сортировка результатов поиска
По умолчанию совпадения поиска сортируются по _score, оценочному рейтингу, показывающему, насколько хорошо каждый документ соответствует запросу. Чтобы настроить вычисление этих оценок, используйте запрос script_score. Чтобы отсортировать совпадения поиска по другим значениям полей, см. Сортировка результатов поиска.

Выполнение асинхронного поиска
Поиски Elasticsearch разработаны для быстрого выполнения на больших объёмах данных, часто возвращая результаты в миллисекундах. По этой причине поиски по умолчанию являются синхронными. Запрос ожидает полных результатов перед возвратом ответа.

Однако полные результаты могут занимать больше времени для поисков по замороженным индексам или по нескольким кластерам.

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

Таймаут поиска

По умолчанию запросы поиска не имеют таймаута. Запрос ожидает завершения каждого фрагмента перед возвратом ответа.

Хотя асинхронный поиск предназначен для длительных поисков, вы также можете использовать параметр timeout, чтобы указать длительность ожидания завершения каждого фрагмента. Каждый фрагмент собирает попадания в течение указанного периода. Если сбор не завершён к концу периода, Elasticsearch использует только собранные к тому моменту попадания. Общее время ожидания запроса поиска зависит от количества фрагментов, необходимых для поиска, и количества одновременных запросов к фрагментам.

GET /my-index-000001/_search
{
  "timeout": "2s",
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  }
}

Чтобы установить глобальный таймаут для всех запросов поиска в кластере, настройте search.default_search_timeout с помощью API обновления настроек кластера. Эта глобальная продолжительность таймаута используется, если аргумент timeout не указан в запросе. Если глобальный таймаут поиска истечёт до завершения запроса поиска, запрос отменяется с использованием отмены задачи. Настройка search.default_search_timeout по умолчанию равна -1 (без таймаута).

Отмена поиска

Вы можете отменить запрос поиска с помощью API управления задачами. Elasticsearch также автоматически отменяет запрос поиска при закрытии HTTP-соединения вашего клиента. Рекомендуется настроить своего клиента на закрытие HTTP-соединений при прерывании или истечении таймаута запроса поиска.

Отслеживание общего количества попаданий

Как правило, общее количество попаданий нельзя точно подсчитать без посещения всех совпадений, что дорого для запросов, которые соответствуют множеству документов. Параметр track_total_hits позволяет контролировать, как следует отслеживать общее количество попаданий. Учитывая, что часто достаточно иметь нижнюю границу количества попаданий, например «существует как минимум 10000 попаданий», значение по умолчанию равно 10,000. Это означает, что запросы будут точно подсчитывать общее количество попаданий до 10,000 попаданий. Это хороший компромисс для ускорения поисков, если вам не нужно точное количество попаданий после определённого порога.

При установке значения true ответ поиска всегда будет точно отслеживать количество попаданий, соответствующих запросу (например, total.relation всегда будет равно "eq", когда track_total_hits установлено в значение true). В противном случае значение "total.relation", возвращённое в объекте "total" ответа поиска, определяет, как следует интерпретировать "total.value". Значение "gte" означает, что "total.value" является нижней границей общего количества попаданий, соответствующих запросу, а значение "eq" указывает, что "total.value" — это точное значение.

GET my-index-000001/_search
{
  "track_total_hits": true,
  "query": {
    "match" : {
      "user.id" : "elkbee"
    }
  }
}

… возвращает:

{
  "_shards": ...
  "timed_out": false,
  "took": 100,
  "hits": {
    "max_score": 1.0,
    "total" : {
      "value": 2048,    
      "relation": "eq"  
    },
    "hits": ...
  }
}

Общее количество результатов поиска, соответствующих запросу.

Счёт точный (например, "eq" означает равенство).

Также можно установить track_total_hits на целое число. Например, следующий запрос точно отслеживает общее количество результатов поиска, соответствующих запросу, до 100 документов:

GET my-index-000001/_search
{
  "track_total_hits": 100,
  "query": {
    "match": {
      "user.id": "elkbee"
    }
  }
}

hits.total.relation в ответе укажет, является ли значение, возвращённое в hits.total.value, точным ("eq") или нижней границей общего количества ("gte").

Например, следующий ответ:

{
  "_shards": ...
  "timed_out": false,
  "took": 30,
  "hits": {
    "max_score": 1.0,
    "total": {
      "value": 42,         
      "relation": "eq"     
    },
    "hits": ...
  }
}

42 документа соответствуют запросу

и счёт точный ("eq")

... указывает, что количество результатов поиска, возвращённых в total, является точным.

Если общее количество результатов поиска, соответствующих запросу, больше значения, заданного в track_total_hits, общее количество результатов поиска в ответе укажет, что возвращённое значение является нижней границей:

{
  "_shards": ...
  "hits": {
    "max_score": 1.0,
    "total": {
      "value": 100,         
      "relation": "gte"     
    },
    "hits": ...
  }
}

По меньшей мере 100 документов соответствуют запросу

Это нижняя граница ("gte").

Если вам не нужно отслеживать общее количество результатов поиска, вы можете улучшить время выполнения запроса, установив это значение в false:

GET my-index-000001/_search
{
  "track_total_hits": false,
  "query": {
    "match": {
      "user.id": "elkbee"
    }
  }
}

... возвращает:

{
  "_shards": ...
  "timed_out": false,
  "took": 10,
  "hits": {             
    "max_score": 1.0,
    "hits": ...
  }
}

Общее количество результатов неизвестно.

Наконец, вы можете принудительно установить точное количество, установив "track_total_hits" на true в запросе.

Быстрый поиск совпадающих документов

Если вам нужно только узнать, существуют ли документы, соответствующие определённому запросу, вы можете установить size на 0, чтобы указать, что нас не интересуют результаты поиска. Вы также можете установить terminate_after на 1, чтобы указать, что выполнение запроса может быть прервано, как только будет найден первый соответствующий документ (по фрагменту).

GET /_search?q=user.id:elkbee&size=0&terminate_after=1

terminate_after всегда применяется после post_filter и останавливает выполнение запроса, а также выполнение агрегаций, когда на фрагменте было собрано достаточно результатов. Хотя количество документов в агрегациях может не отражать hits.total в ответе, так как агрегации применяются до дополнительного фильтра.

Ответ не будет содержать результатов поиска, так как size было установлено на 0. hits.total будет равно 0, указывая, что соответствующих документов не было, или больше 0, что означает, что при раннем прерывании запроса по меньшей мере столько документов соответствовало запросу. Также, если запрос был прерван на ранней стадии, флаг terminated_early будет установлен на true в ответе.

{
  "took": 3,
  "timed_out": false,
  "terminated_early": true,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

Время took в ответе содержит миллисекунды, потраченные на обработку этого запроса, начиная сразу после получения узлом запроса и до возвращения вышеуказанного JSON-объекта клиенту. Это означает, что оно включает время ожидания в пулах потоков, выполнение распределённого поиска по всему кластеру и сбор всех результатов.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-your-data.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API