Сворачивание результатов поиска
Вы можете использовать параметр collapse для сворачивания результатов поиска на основе значений поля. Сворачивание выполняется путем выбора только документа с наивысшим значением сортировки по ключу сворачивания.
Например, следующий поиск сворачивает результаты по полю user.id и сортирует их по полю http.response.bytes.
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "GET /search"
}
},
collapse={
"field": "user.id"
},
sort=[
{
"http.response.bytes": {
"order": "desc"
}
}
],
from_=0,
)
print(resp) const response = await client.search({
index: "my-index-000001",
query: {
match: {
message: "GET /search",
},
},
collapse: {
field: "user.id",
},
sort: [
{
"http.response.bytes": {
order: "desc",
},
},
],
from: 0,
});
console.log(response); GET my-index-000001/_search
{
"query": {
"match": {
"message": "GET /search"
}
},
"collapse": {
"field": "user.id"
},
"sort": [
{
"http.response.bytes": {
"order": "desc"
}
}
],
"from": 0
} | Свернуть результаты с использованием поля | |
| Сортировать результаты по полю | |
| Определить смещение первого свёрнутого результата |
Общее количество совпадений в ответе указывает на количество документов, соответствующих запросу, без сворачивания. Общее количество различных групп неизвестно.
Поле, используемое для сворачивания, должно быть однозначным полем типа keyword или numeric с активированными doc_values.
Сворачивание применяется только к верхним результатам и не влияет на агрегации.
Развернуть свёрнутые результаты
Также возможно развернуть каждый свёрнутый верхний результат с помощью опции inner hits.
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "GET /search"
}
},
collapse={
"field": "user.id",
"inner_hits": {
"name": "most_recent",
"size": 5,
"sort": [
{
"@timestamp": "desc"
}
]
},
"max_concurrent_group_searches": 4
},
sort=[
{
"http.response.bytes": {
"order": "desc"
}
}
],
)
print(resp) const response = await client.search({
index: "my-index-000001",
query: {
match: {
message: "GET /search",
},
},
collapse: {
field: "user.id",
inner_hits: {
name: "most_recent",
size: 5,
sort: [
{
"@timestamp": "desc",
},
],
},
max_concurrent_group_searches: 4,
},
sort: [
{
"http.response.bytes": {
order: "desc",
},
},
],
});
console.log(response); GET /my-index-000001/_search
{
"query": {
"match": {
"message": "GET /search"
}
},
"collapse": {
"field": "user.id",
"inner_hits": {
"name": "most_recent",
"size": 5,
"sort": [ { "@timestamp": "desc" } ]
},
"max_concurrent_group_searches": 4
},
"sort": [
{
"http.response.bytes": {
"order": "desc"
}
}
]
} | Свернуть результат с использованием поля | |
| Имя, используемое для раздела внутреннего результата в ответе | |
| Количество | |
| Как сортировать документы внутри каждой группы | |
| Количество одновременных запросов, разрешенных для получения |
См. внутренние результаты для получения полного списка поддерживаемых параметров и формата ответа.
Также можно запросить несколько inner hits для каждого свёрнутого результата. Это может быть полезно, когда требуется получить несколько представлений свёрнутых результатов.
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "GET /search"
}
},
collapse={
"field": "user.id",
"inner_hits": [
{
"name": "largest_responses",
"size": 3,
"sort": [
{
"http.response.bytes": {
"order": "desc"
}
}
]
},
{
"name": "most_recent",
"size": 3,
"sort": [
{
"@timestamp": {
"order": "desc"
}
}
]
}
]
},
sort=[
"http.response.bytes"
],
)
print(resp) const response = await client.search({
index: "my-index-000001",
query: {
match: {
message: "GET /search",
},
},
collapse: {
field: "user.id",
inner_hits: [
{
name: "largest_responses",
size: 3,
sort: [
{
"http.response.bytes": {
order: "desc",
},
},
],
},
{
name: "most_recent",
size: 3,
sort: [
{
"@timestamp": {
order: "desc",
},
},
],
},
],
},
sort: ["http.response.bytes"],
});
console.log(response); GET /my-index-000001/_search
{
"query": {
"match": {
"message": "GET /search"
}
},
"collapse": {
"field": "user.id",
"inner_hits": [
{
"name": "largest_responses",
"size": 3,
"sort": [
{
"http.response.bytes": {
"order": "desc"
}
}
]
},
{
"name": "most_recent",
"size": 3,
"sort": [
{
"@timestamp": {
"order": "desc"
}
}
]
}
]
},
"sort": [
"http.response.bytes"
]
} | Свернуть результат с использованием поля | |
| Возвратить три наибольших HTTP-ответа для пользователя | |
| Возвратить три самых последних HTTP-ответа для пользователя |
Расширение группы выполняется путем отправки дополнительного запроса для каждого запроса inner_hit для каждого свёрнутого результата, возвращенного в ответе. Это может значительно замедлить поиск, если у вас слишком много групп или запросов inner_hit.
Параметр запроса max_concurrent_group_searches может использоваться для управления максимальным количеством одновременных поисков, разрешенных на этой стадии. Значение по умолчанию основано на количестве узлов данных и размере пула потоков поиска по умолчанию.
collapse не может использоваться совместно с прокруткой.
Сворачивание с search_after
Сворачивание по полю может использоваться с параметром search_after. Использование search_after поддерживается только при сортировке и сворачивании по одному и тому же полю. Вторичная сортировка также запрещена. Например, мы можем свернуть и отсортировать по полю user.id, просматривая результаты с помощью search_after:
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "GET /search"
}
},
collapse={
"field": "user.id"
},
sort=[
"user.id"
],
search_after=[
"dd5ce1ad"
],
)
print(resp) const response = await client.search({
index: "my-index-000001",
query: {
match: {
message: "GET /search",
},
},
collapse: {
field: "user.id",
},
sort: ["user.id"],
search_after: ["dd5ce1ad"],
});
console.log(response); GET /my-index-000001/_search
{
"query": {
"match": {
"message": "GET /search"
}
},
"collapse": {
"field": "user.id"
},
"sort": [ "user.id" ],
"search_after": ["dd5ce1ad"]
} Переоценка результатов сворачивания
Вы можете использовать сворачивание по полю вместе с параметром поиска rescore. Переоценщики запускаются на каждом фрагменте для документа с наивысшим рейтингом по свёрнутому полю. Для обеспечения надежного порядка рекомендуется кластеризовать документы, имеющие одинаковое значение поля сворачивания, на одном фрагменте. Это достигается путем назначения значения поля сворачивания в качестве ключа маршрутизации во время индексирования:
resp = client.index(
index="my-index-000001",
routing="xyz",
document={
"@timestamp": "2099-11-15T13:12:00",
"message": "You know for search!",
"user.id": "xyz"
},
)
print(resp) const response = await client.index({
index: "my-index-000001",
routing: "xyz",
document: {
"@timestamp": "2099-11-15T13:12:00",
message: "You know for search!",
"user.id": "xyz",
},
});
console.log(response); POST /my-index-000001/_doc?routing=xyz
{
"@timestamp": "2099-11-15T13:12:00",
"message": "You know for search!",
"user.id": "xyz"
} | Назначить маршрутизацию со значением поля сворачивания ( |
Благодаря этому гарантируется, что только один верхний документ по ключу сворачивания будет переоценен глобально.
Следующий запрос использует сворачивание по полю user.id, а затем переоценивает верхние группы с помощью переоценщика запросов:
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "you know for search"
}
},
collapse={
"field": "user.id"
},
rescore={
"window_size": 50,
"query": {
"rescore_query": {
"match_phrase": {
"message": "you know for search"
}
},
"query_weight": 0.3,
"rescore_query_weight": 1.4
}
},
)
print(resp) const response = await client.search({
index: "my-index-000001",
query: {
match: {
message: "you know for search",
},
},
collapse: {
field: "user.id",
},
rescore: {
window_size: 50,
query: {
rescore_query: {
match_phrase: {
message: "you know for search",
},
},
query_weight: 0.3,
rescore_query_weight: 1.4,
},
},
});
console.log(response); GET /my-index-000001/_search
{
"query": {
"match": {
"message": "you know for search"
}
},
"collapse": {
"field": "user.id"
},
"rescore" : {
"window_size" : 50,
"query" : {
"rescore_query" : {
"match_phrase": {
"message": "you know for search"
}
},
"query_weight" : 0.3,
"rescore_query_weight" : 1.4
}
}
} Переоценщики не применяются к inner hits.
Сворачивание второго уровня
Поддерживается и сворачивание второго уровня, которое применяется к inner_hits.
Например, следующий поиск сворачивает результаты по полю geo.country_name. Внутри каждой geo.country_name внутренние результаты свёрнуты по полю user.id.
Сворачивание второго уровня не позволяет использовать inner_hits.
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "GET /search"
}
},
collapse={
"field": "geo.country_name",
"inner_hits": {
"name": "by_location",
"collapse": {
"field": "user.id"
},
"size": 3
}
},
)
print(resp) const response = await client.search({
index: "my-index-000001",
query: {
match: {
message: "GET /search",
},
},
collapse: {
field: "geo.country_name",
inner_hits: {
name: "by_location",
collapse: {
field: "user.id",
},
size: 3,
},
},
});
console.log(response); GET /my-index-000001/_search
{
"query": {
"match": {
"message": "GET /search"
}
},
"collapse": {
"field": "geo.country_name",
"inner_hits": {
"name": "by_location",
"collapse": { "field": "user.id" },
"size": 3
}
}
} {
"hits" : {
"hits" : [
{
"_index" : "my-index-000001",
"_id" : "oX9uXXoB0da05OCR3adK",
"_score" : 0.5753642,
"_source" : {
"@timestamp" : "2099-11-15T14:12:12",
"geo" : {
"country_name" : "Amsterdam"
},
"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"
}
},
"fields" : {
"geo.country_name" : [
"Amsterdam"
]
},
"inner_hits" : {
"by_location" : {
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "my-index-000001",
"_id" : "oX9uXXoB0da05OCR3adK",
"_score" : 0.5753642,
"_source" : {
"@timestamp" : "2099-11-15T14:12:12",
"geo" : {
"country_name" : "Amsterdam"
},
"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"
}
},
"fields" : {
"user.id" : [
"kimchy"
]
}
}
]
}
}
}
}
]
}
} Отслеживание оценок
Когда collapse используется с sort по полю, оценки не вычисляются. Установка track_scores в значение true инструктирует Elasticsearch вычислять и отслеживать оценки.
© 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/collapse-search-results.html