В этой статье в основном подробно представлены часто используемые операторы запросов в es, а также некоторые вопросы, требующие внимания при их использовании.
Если вы не знаете es, рекомендуется сначала прочитать основные понятия es:nuggets.capable/post/684490…
поиск по параметру URL
Этот метод аналогичен запросу get, где параметры запроса склеиваются со ссылкой, напримерGET /school/student/_search?参数
, несколько параметров разделяются знаком &
запросить все
Заказ:GET /school/student/_search
возвращение:
{
"took": 7, //查询耗时,毫秒
"timed_out": false, //是否超时,timeout 不是停止执行查询,它仅仅是告知正在协调的节点返回到目前为止收集的结果并且关闭连接
"_shards": {
"total": 5, //请求的分片数量,索引拆成了5个分片,所以对于搜索请求,会打到所有的primary shard
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2, //符合条件的总条数,这里查的是所有
"max_score": 1, //匹配分数
"hits": [ //数据
{
"_index": "school",
"_type": "student",
"_id": "2",
"_score": 1,
"_source": {
"name": "houyi",
"age": 23,
"class": 2,
"gender": "男"
}
},
{
"_index": "school",
"_type": "student",
"_id": "1",
"_score": 1,
"_source": {
"name": "吕布",
"age": 21,
"class": 2,
"gender": "男"
}
}
]
}
}
Многоиндексный, многотипный поиск
Укажите специальный индекс и введите URL-адрес для многоиндексного и многотипного поиска.
-
/_search
: Поиск всех типов во всех индексах -
/school/_search
:существуетschool
Искать все типы в индексе -
/school,ad/_search
:существуетschool
иad
Искать все типы в индексе -
/s*,a*/_search
: в целомg
иa
все типы в индексе, начиная с -
/school/student/_search
:существуетschool
Поиск в индексеstudent
тип -
/school,ad/student,phone/_search
:существуетschool
иad
поиск по индексуstudent
иphone
тип -
/_all/student,phone/_search
: поиск по всем индексамstudent
иphone
тип
Запрос по условию
Заказ:GET /school/student/_search?q=name:houyi
Запросить записи, чье имя houyi
Дополнительные параметры запроса:
Запрос DSL
Elasticsearch предоставляет полный DSL запросов на основе JSON для определения запросов. DSL имеет набор компонентов запроса, которые можно сопоставлять в бесконечных комбинациях для создания различных сложных запросов.
заявление листа
Оператор листа: как и оператор соответствия, он используется для сравнения строки запроса с полем или полями (одно условие). Например:
GET /ad/phone/_search
{
"query": {
"match": {
"name": "phone"
}
}
}
Составной запрос
Пользователь объединяет другие операторы запроса, такие какbool
оператор, позволяющий комбинировать другие операторы по мере необходимости, в том числеmust
,must_not
,should
иfilter
Заявление (запрос комбинации нескольких условий)
Например:
GET /ad/phone/_search
{
"query": {
"bool": {
"must": [
{"match": {
"name": "phone"
}}
]
, "must_not": [
{"match": {
"color": "red"
}}
]
, "should": [
{"match": {
"price": 5000
}}
]
, "filter": {
"term": {
"label": "phone"
}
}
}
}
}
must
: указывает, что документ должен содержать содержимое запроса
must_not
: указывает, что документ не должен содержать содержимое запроса
should
: Указывает, что оценка релевантности документа может быть увеличена, если документ соответствует
На самом деле мы можем использовать два структурированных оператора: Структурированные запросы.query DSL
и структурированная фильтрацияFilter DSL
-
структурированный запрос
query DSL
Он используется для проверки соответствия содержимого условиям. Предложения bool и match, используемые в запросе содержимого, используются для расчета оценки соответствия каждого документа. Метаполе _score указывает степень соответствия. Структура запроса начинается с параметра запроса для выполнения запроса содержимого.
-
структурированная фильтрация
Filter DSL
Он просто определяет, соответствует ли документ.Предложения термина и диапазона, используемые при фильтрации содержимого, будут отфильтровывать документы, которые не соответствуют, и не будут влиять на расчет оценки соответствия документа.
Использование фильтров запросов будет автоматически кэшироваться es для повышения эффективности.
В принципе, при использовании оператора запроса для полнотекстового поиска или другой оценки релевантности используйте операторы фильтра для остальных.
Создайте немного более сложный индекс и добавьте три документа
PUT /ad/phone/1
{
"name":"phone 8",
"price": 6000,
"color":"white",
"ad":"this is a white phone",
"label":["white","nice"]
}
PUT /ad/phone/2
{
"name":"xiaomi 8",
"price": 4000,
"color":"red",
"ad":"this is a red phone",
"label":["white","xiaomi"]
}
PUT /ad/phone/3
{
"name":"huawei p30",
"price": 5000,
"color":"white",
"ad":"this is a white phone",
"label":["white","huawei"]
}
Пример запроса
1. Получить все
GET /ad/phone/_search
{
"query": {
"match_all": {}
}
}
match_all
Сопоставьте все данные и верните метаполе в результат_score
оценка 1
2. Пейджинговый запрос, начиная со второго, отмечаем два (не использоватьfrom
,size
Для глубокого пейджинга будут проблемы с производительностью)
GET /ad/phone/_search
{
"query": {
"match_all": {}
},
"from": 1,
"size": 2
}
Если этот метод разбиения на страницы выполняет глубокое разбиение по страницам, например, на 100 страниц с десятью фрагментами данных на странице, он будет запрашивать 100 * 10 фрагментов данных из каждого сегмента. Предположим, что имеется пять сегментов, то есть 5000 фрагментов данных, и затем сохранить их в памяти.Отсортировать по порядку, а затем вернуть 1000-1010-е данные в коллекции после взятия последовательности
3. Укажите поля, возвращаемые запрошенными данными.
GET /ad/phone/_search
{
"query": {
"match_all": {}
},
"_source": ["name","price"]
}
В возвращаемых данных только returnname
иprice
поле
4. Поле объявления содержит слово белый
GET /ad/phone/_search
{
"query": {
"match": {
"ad": "white"
}
}
}
Метаполя в возвращаемом результате_score
Есть рейтинги, инструкция по применениюquery
оценка будет рассчитана
5. Поле объявления содержит слово белый и отсортировано по цене в порядке возрастания
GET /ad/phone/_search
{
"query": {
"match": {
"ad": "white"
}
},
"sort": [
{
"price": {
"order": "asc"
}
}
]
}
6. Поле цены больше 5000
GET /ad/phone/_search
{
"query": {
"bool": {
"filter": {
"range": {
"price": {
"gt": 5000
}
}
}
}
}
}
Метаполя в возвращаемом результате_score
Поле равно 0, нет баллов, что указывает на использованиеfilter
Рейтинг не будет рассчитываться
7. Поле объявления содержит слово белый, а поле цены больше 5000
GET /ad/phone/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"ad": "white"
}
}
],
"filter": {
"range": {
"price": {
"gt": 5000
}
}
}
}
}
}
8. Запросname
поле содержит словаphone
количество документов
GET /ad/phone/_count
{
"query": {
"match": {
"name": "phone"
}
}
}
Подробное объяснение ключевых слов
1. match_all
Запрос
Запрос просто соответствует всем документам
GET /ad/phone/_search
{
"query": {
"match_all": {}
}
}
2. match
Запрос
Поддерживается полнотекстовый поиск и точный запрос, в зависимости от того, поддерживает ли поле полнотекстовый поиск.
Полнотекстовый поиск:
GET /ad/phone/_search
{
"query": {
"match": {
"ad": "a red"
}
}
}
Полнотекстовый поиск сначала выполнит сегментацию слов в строке запроса.a red
будет разделен наa
иred
, а затем сопоставить в инвертированном индексе, поэтому этот оператор найдет все три документа
Точный запрос:
GET /ad/phone/_search
{
"query": {
"match": {
"price": "6000"
}
}
}
Для запросов с точным значением вместо запроса можно использовать оператор фильтра, поскольку фильтр будет кэшироваться.
operator
работать:
match
Также принимаются запросыoperator
оператор в качестве входного параметра, по умолчанию операторor
. мы можем изменить его наand
сделать так, чтобы все указанные термины совпадали
GET /ad/phone/_search
{
"query": {
"match": {
"ad": {
"query": "a red",
"operator": "and"
}
}
}
}
Точное совпадение:
match
Поддержка запросовminimum_should_match
Параметр минимального соответствия может указывать количество терминов, которые должны сопоставляться, чтобы указать, связан ли документ. Мы можем установить его на конкретное число (имеется в виду количество слов, которые должны соответствовать инвертированному индексу), чаще устанавливается в процентах, потому что мы не можем контролировать количество слов, которые пользователи вводят при поиске.
GET /ad/phone/_search
{
"query": {
"match": {
"ad": {
"query": "a red",
"minimum_should_match": "2"
}
}
}
}
будет возвращать только совпаденияa
иred
Документ из двух слов возвращается, еслиminimum_should_match
равен 1, то пока одно из слов совпадает, документ будет возвращен
3. multi_match
Запрос
Запрос с несколькими полями, например запросcolor
иad
поле содержит словаred
документация
GET /ad/phone/_search
{
"query": {
"multi_match": {
"query": "red",
"fields": ["color","ad"]
}
}
}
4. range
Запрос
Запрос диапазона, запрос документов, цена которых больше 4000 и меньше 6000
GET /ad/phone/_search
{
"query": {
"range": {
"price": {
"gt": 4000,
"lt": 6000
}
}
}
}
Оператор запроса диапазона:gt
(больше, чем),gte
(больше или равно),lt
(меньше, чем),lte
(меньше или равно);
5. term
Запрос
Запрос точного значения
Запросprice
Документы с полями, равными 6000
GET /ad/phone/_search
{
"query": {
"term": {
"price": {
"value": "6000"
}
}
}
}
Запросname
поле равноphone 8
документация
GET /ad/phone/_search
{
"query": {
"term": {
"name": {
"value": "phone 8"
}
}
}
}
Возвращаемое значение выглядит следующим образом, имя не запрашиваетсяphone 8
документация
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
почему не нашелphone 8
Этот документ должен быть представлен здесьterm
Принцип запроса
term
Запрос пойдет к инвертированному индексу, чтобы найти точныйterm
, он не попадет в токенизатор, будет соответствовать только инвертированному индексу, иname
полеtype
типtext
, выполнит сегментацию слов, будетphone 8
разделен наphone
и8
,Мы используемterm
Запросphone 8
не в инвертированном индексеphone 8
, поэтому не было запрошено ни одного совпадающего документа
term
запрос сmatch
разница запросов
-
term
При запросе не будет сегментации слов, а инвертированный индекс будет сопоставляться напрямую -
match
Сегментация слов будет выполняться при запросе, запросphone 8
, сначала будет причастием вphone
и8
, а затем соответствовать инвертированному индексу, поэтому результат будетphone 8
иxiaomi 8
Оба документа найдены.
Следует отметить еще одну вещь, посколькуterm
Запрос не будет проходить через токенизатор, а вернется к совпадению с инвертированным индексом, поэтому структура запроса связана с тем, как токенизатор разделяет слова, например, добавляет новое./ad/phone
документ под типом,name
поле назначается какOppo
, затем используйтеterm
ЗапросOppo
Документ не будет запрошен, так как по умолчанию используется es.standard
Tokenizer, который преобразует слова в строчные буквы после токенизации, поэтому используйтеoppo
Не могу найти документацию, используйте строчные буквыoppo
можно найти
GET /ad/phone/_search
{
"query": {
"term": {
"name": {
"value": "Oppo" //改成oppo可以查出新添加的文档
}
}
}
}
Это не значит, что вы понимаетеstandard
токенизатор, но чтобы получить все какterm
Этот тип результата запроса связан с выбранным токенизатором. Понимание выбранного токенизатора поможет нам написать операторы запроса.
6. terms
Запрос
terms
запрос сterm
То же, что запрос, но позволяет указать, сколько совпадений должно совпадать.Если поле содержит какое-либо из указанных значений, то документ удовлетворяет условию
GET /ad/phone/_search
{
"query": {
"terms": {
"ad": ["red","blue"]
}
}
}
7. exists
запрос иmissing
Запрос
Используется для поиска этих значений в указанном поле (exists
) или без значения (missing
) документация
уточнитьname
Поля имеют значения:
GET /ad/phone/_search
{
"query": {
"bool": {
"filter": {
"exists": {
"field": "name"
}
}
}
}
}
уточнитьname
Поле не имеет значения:
GET /ad/phone/_search
{
"query": {
"bool": {
"filter": {
"missing": {
"field": "name"
}
}
}
}
}
8. match_phrase
Запрос
Фразовый запрос, точное соответствие, запросa red
будет соответствоватьad
поле содержитa red
Фраза без запроса сегментации слов и не будет содержать запросa 其他词 red
такой документ
GET /ad/phone/_search
{
"query": {
"match_phrase": {
"ad": "a red"
}
}
}
9. scroll
Запрос
Подобно пейджинговому запросу, он не поддерживает запрос перехода на страницу и может запрашивать только одну страницу за раз.scroll
Запросы предназначены не для пользовательских запросов в реальном времени, а для обработки больших объемов данных, например, для переиндексации содержимого одного индекса в новый индекс с другой конфигурацией.
POST /ad/phone/_search?scroll=1m
{
"query": {
"match_all": {}
},
"size": 1,
"from": 0
}
Возвращаемое значение содержит"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAAQFlV6T3VqY2NaVDBLRG5uZXdiZ0hFYUEAAAAAAAAAERZVek91amNjWlQwS0RubmV3YmdIRWFBAAAAAAAAABIWVXpPdWpjY1pUMEtEbm5ld2JnSEVhQQAAAAAAAAATFlV6T3VqY2NaVDBLRG5uZXdiZ0hFYUEAAAAAAAAAFBZVek91amNjWlQwS0RubmV3YmdIRWFB"
Используйте его в следующем запросе_scroll_id
Вы можете запросить документы на следующей странице
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAAYFlV6T3VqY2NaVDBLRG5uZXdiZ0hFYUEAAAAAAAAAGRZVek91amNjWlQwS0RubmV3YmdIRWFBAAAAAAAAABYWVXpPdWpjY1pUMEtEbm5ld2JnSEVhQQAAAAAAAAAXFlV6T3VqY2NaVDBLRG5uZXdiZ0hFYUEAAAAAAAAAFRZVek91amNjWlQwS0RubmV3YmdIRWFB"
}
10. multi get
Запрос
Позволяет извлекать несколько документов на основе индекса, типа (необязательно) и идентификатора (и, возможно, маршрута), включая информацию об ошибке в ответ, если документ не может быть извлечен
```json
GET /ad/phone/_mget
{
"ids": ["1","8"]
}
```
11. bulk
Массовые операции
bulk
Массовые операции могут реализовывать несколько документов в одном вызове API.create
,index
,update
илиdelete
. Это может значительно повысить скорость индексации.
bulk
Тело запроса выглядит следующим образом
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
...
actionДолжен быть одним из следующих:
поведение | объяснять |
---|---|
create | Создается, когда документ не существует |
index | Создайте новый документ или замените существующий документ |
update | Частично обновить документацию |
delete | удалить документ |
Документы необходимо указывать при индексировании, создании, обновлении или удалении_index
,_type
,_id
Эти метаданные (metadata
)
пример:
PUT _bulk
{ "create" : { "_index" : "ad", "_type" : "phone", "_id" : "6" }}
{ "doc" : {"name" : "bulk"}}
{ "index" : { "_index" : "ad", "_type" : "phone", "_id" : "6" }}
{ "doc" : {"name" : "bulk"}}
{ "delete":{ "_index" : "ad", "_type" : "phone", "_id" : "1"}}
{ "update":{ "_index" : "ad", "_type" : "phone", "_id" : "3"}}
{ "doc" : {"name" : "huawei p20"}}
возвращение:
{
"took": 137,
"errors": true, //如果任意一个文档出错,这里返回true,
"items": [ //items数组,它罗列了每一个请求的结果,结果的顺序与我们请求的顺序相同
{
//create这个文档已经存在,所以异常
"create": {
"_index": "ad",
"_type": "phone",
"_id": "6",
"status": 409,
"error": {
"type": "version_conflict_engine_exception",
"reason": "[phone][6]: version conflict, document already exists (current version [2])",
"index_uuid": "9F5FHqgISYOra_P09HReVQ",
"shard": "2",
"index": "ad"
}
}
},
{
//index这个文档已经存在,会覆盖
"index": {
"_index": "ad",
"_type": "phone",
"_id": "6",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 6,
"_primary_term": 5,
"status": 200
}
},
{
//删除
"delete": {
"_index": "ad",
"_type": "phone",
"_id": "1",
"_version": 1,
"result": "not_found",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 4,
"_primary_term": 5,
"status": 404
}
},
{
//修改
"update": {
"_index": "ad",
"_type": "phone",
"_id": "3",
"_version": 3,
"result": "noop",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"status": 200
}
}
]
}
bulk
Запросы не являются атомарными операциями, они не могут реализовывать транзакции. Каждый запрос обрабатывается отдельно, поэтому успех каждого запроса не мешает другим операциям.
12. fuzzy
Запрос
нечеткий запрос,fuzzy
Запрос вычисляет сходство написания с ключевым словом
GET /ad/phone/_search
{
"query": {
"fuzzy": {
"color":{
"value": "res"
, "fuzziness": 2,
"prefix_length": 1
}
}
}
}
настройки параметров:
fuzziness
: максимальное расстояние редактирования, по умолчаниюAUTO
prefix_length
: начальное количество символов, которые не будут «затенены». Это помогает уменьшить количество терминов, которые необходимо проверить, по умолчанию0
max_expansions
:fuzzy
Максимальное количество терминов, до которых будет расширяться запрос. По умолчанию50
, установите значение small, чтобы оптимизировать запросы
transpositions
: Поддерживается ли нечеткое транспонирование (ab
→ba
), значение по умолчаниюfalse
13. wildcard
Запрос
Нечеткие запросы, поддерживающие подстановочные знаки, ? соответствует одному символу, * соответствует любому символу
Чтобы предотвратить чрезвычайно медленные запросы с подстановочными знаками,*
или?
Подстановочные элементы не должны размещаться в начале подстановочного знака.
GET /ad/phone/_search
{
"query": {
"wildcard": {
"color": "r?d"
}
}
}
Продолжение следует...