Сортировка индекса
При создании нового индекса в Elasticsearch можно настроить порядок сортировки сегментов внутри каждого фрагмента. По умолчанию Lucene не применяет никакой сортировки. Настройки index.sort.* определяют, какие поля должны использоваться для сортировки документов внутри каждого сегмента.
Разрешается применять сортировку индекса к отображениям с вложенными объектами, при условии, что в настройке index.sort.* отсутствуют вложенные поля.
Например, следующий пример демонстрирует, как определить сортировку по одному полю:
resp = client.indices.create(
index="my-index-000001",
settings={
"index": {
"sort.field": "date",
"sort.order": "desc"
}
},
mappings={
"properties": {
"date": {
"type": "date"
}
}
},
)
print(resp) response = client.indices.create(
index: 'my-index-000001',
body: {
settings: {
index: {
'sort.field' => 'date',
'sort.order' => 'desc'
}
},
mappings: {
properties: {
date: {
type: 'date'
}
}
}
}
)
puts response const response = await client.indices.create({
index: "my-index-000001",
settings: {
index: {
"sort.field": "date",
"sort.order": "desc",
},
},
mappings: {
properties: {
date: {
type: "date",
},
},
},
});
console.log(response); PUT my-index-000001
{
"settings": {
"index": {
"sort.field": "date",
"sort.order": "desc"
}
},
"mappings": {
"properties": {
"date": {
"type": "date"
}
}
}
} | Этот индекс отсортирован по полю | |
| … в порядке убывания. |
Также можно отсортировать индекс по нескольким полям:
resp = client.indices.create(
index="my-index-000001",
settings={
"index": {
"sort.field": [
"username",
"date"
],
"sort.order": [
"asc",
"desc"
]
}
},
mappings={
"properties": {
"username": {
"type": "keyword",
"doc_values": True
},
"date": {
"type": "date"
}
}
},
)
print(resp) response = client.indices.create(
index: 'my-index-000001',
body: {
settings: {
index: {
'sort.field' => [
'username',
'date'
],
'sort.order' => [
'asc',
'desc'
]
}
},
mappings: {
properties: {
username: {
type: 'keyword',
doc_values: true
},
date: {
type: 'date'
}
}
}
}
)
puts response const response = await client.indices.create({
index: "my-index-000001",
settings: {
index: {
"sort.field": ["username", "date"],
"sort.order": ["asc", "desc"],
},
},
mappings: {
properties: {
username: {
type: "keyword",
doc_values: true,
},
date: {
type: "date",
},
},
},
});
console.log(response); PUT my-index-000001
{
"settings": {
"index": {
"sort.field": [ "username", "date" ],
"sort.order": [ "asc", "desc" ]
}
},
"mappings": {
"properties": {
"username": {
"type": "keyword",
"doc_values": true
},
"date": {
"type": "date"
}
}
}
} | Этот индекс отсортирован по полю | |
| … в порядке возрастания для поля |
Сортировка индекса поддерживает следующие настройки:
-
index.sort.field - Список полей, используемых для сортировки индекса. Здесь разрешены только поля
boolean,numeric,dateиkeywordс типомdoc_values. -
index.sort.order -
Порядок сортировки для каждого поля. Опция order может принимать следующие значения:
-
asc: Для возрастания -
desc: Для убывания.
-
-
index.sort.mode -
Elasticsearch поддерживает сортировку по многозначным полям. Опция mode управляет тем, какое значение выбирается для сортировки документа. Опция mode может принимать следующие значения:
-
min: Выбрать наименьшее значение. -
max: Выбрать наибольшее значение.
-
-
index.sort.missing -
Параметр missing определяет, как должны обрабатываться документы, у которых поле отсутствует. Значение missing может принимать следующие значения:
-
_last: Документы без значения для поля сортируются последними. -
_first: Документы без значения для поля сортируются первыми.
-
Сортировка индекса может быть определена только один раз при создании индекса. Добавление или обновление сортировки в существующем индексе не разрешается. Сортировка индекса также связана с затратами на производительность индексации, так как документы должны быть отсортированы во время слияния и записи в кэш. Перед активацией этой функции следует проверить её влияние на ваше приложение.
Раннее завершение запроса поиска
По умолчанию в Elasticsearch запрос поиска должен посетить каждый документ, соответствующий запросу, чтобы получить лучшие документы, отсортированные по заданной сортировке. Однако, если сортировка индекса и сортировка поиска совпадают, можно ограничить количество документов, которые должны быть посещены в каждом сегменте для получения N лучших документов в глобальном масштабе. Например, предположим, что у нас есть индекс, содержащий события, отсортированные по полю timestamp:
resp = client.indices.create(
index="events",
settings={
"index": {
"sort.field": "timestamp",
"sort.order": "desc"
}
},
mappings={
"properties": {
"timestamp": {
"type": "date"
}
}
},
)
print(resp) response = client.indices.create(
index: 'events',
body: {
settings: {
index: {
'sort.field' => 'timestamp',
'sort.order' => 'desc'
}
},
mappings: {
properties: {
timestamp: {
type: 'date'
}
}
}
}
)
puts response const response = await client.indices.create({
index: "events",
settings: {
index: {
"sort.field": "timestamp",
"sort.order": "desc",
},
},
mappings: {
properties: {
timestamp: {
type: "date",
},
},
},
});
console.log(response); PUT events
{
"settings": {
"index": {
"sort.field": "timestamp",
"sort.order": "desc"
}
},
"mappings": {
"properties": {
"timestamp": {
"type": "date"
}
}
}
} | Этот индекс отсортирован по timestamp в порядке убывания (самые последние события вначале) |
Вы можете найти последние 10 событий с помощью:
resp = client.search(
index="events",
size=10,
sort=[
{
"timestamp": "desc"
}
],
)
print(resp) response = client.search(
index: 'events',
body: {
size: 10,
sort: [
{
timestamp: 'desc'
}
]
}
)
puts response const response = await client.search({
index: "events",
size: 10,
sort: [
{
timestamp: "desc",
},
],
});
console.log(response); GET /events/_search
{
"size": 10,
"sort": [
{ "timestamp": "desc" }
]
} Elasticsearch обнаружит, что лучшие документы в каждом сегменте уже отсортированы в индексе, и будет сравнивать только первые N документов в каждом сегменте. Остальные документы, соответствующие запросу, собираются для подсчёта общего числа результатов и построения агрегаций.
Если вам нужны только последние 10 событий и вас не интересует общее количество документов, соответствующих запросу, можно установить track_total_hits в значение false:
resp = client.search(
index="events",
size=10,
sort=[
{
"timestamp": "desc"
}
],
track_total_hits=False,
)
print(resp) response = client.search(
index: 'events',
body: {
size: 10,
sort: [
{
timestamp: 'desc'
}
],
track_total_hits: false
}
)
puts response const response = await client.search({
index: "events",
size: 10,
sort: [
{
timestamp: "desc",
},
],
track_total_hits: false,
});
console.log(response); GET /events/_search
{
"size": 10,
"sort": [
{ "timestamp": "desc" }
],
"track_total_hits": false
} | Сортировка индекса будет использоваться для ранжирования лучших документов, и каждый сегмент будет преждевременно завершать сбор после первых 10 совпадений. |
На этот раз Elasticsearch не будет пытаться посчитать количество документов и сможет завершить запрос сразу после сбора N документов в каждом сегменте.
{
"_shards": ...
"hits" : {
"max_score" : null,
"hits" : []
},
"took": 20,
"timed_out": false
} | Общее число совпадений с запросом неизвестно из-за преждевременного завершения. |
Агрегации будут собирать все документы, соответствующие запросу, независимо от значения track_total_hits
© 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/8.17/index-modules-index-sorting.html