検索結果の折りたたみ
フィールド値に基づいて検索結果を折りたたむには、collapse
パラメータを使用できます。折りたたみは、各折りたたみキーごとに上位のソートされたドキュメントのみを選択することによって行われます。
たとえば、次の検索はuser.id
で結果を折りたたみ、http.response.bytes
でソートします。
Python
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)
Js
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
}
user.id フィールドを使用して結果セットを折りたたむ |
|
http.response.bytes で結果をソートする |
|
最初の折りたたまれた結果のオフセットを定義する |
レスポンス内のヒットの総数は、折りたたみなしで一致するドキュメントの数を示します。異なるグループの総数は不明です。
折りたたみに使用されるフィールドは、単一値のkeyword
またはnumeric
フィールドで、doc_values
が有効になっている必要があります。
折りたたみは上位のヒットのみに適用され、集計には影響しません。
折りたたみ結果の展開
inner hits
オプションを使用して、各折りたたまれた上位ヒットを展開することも可能です。
Python
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)
Js
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"
}
}
]
}
user.id フィールドを使用して結果セットを折りたたむ |
|
レスポンス内のインナーヒットセクションに使用される名前 | |
各折りたたみキーごとに取得するinner_hits の数 |
|
各グループ内のドキュメントをソートする方法 | |
各グループごとにinner_hits を取得するために許可される同時リクエストの数 |
サポートされているオプションの完全なリストとレスポンスの形式については、インナーヒットを参照してください。
各折りたたまれたヒットに対して複数のinner hits
をリクエストすることも可能です。これは、折りたたまれたヒットの複数の表現を取得したい場合に便利です。
Python
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)
Js
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"
]
}
user.id フィールドを使用して結果セットを折りたたむ |
|
ユーザーのために3つの最大HTTPレスポンスを返す | |
ユーザーのために3つの最新のHTTPレスポンスを返す |
グループの展開は、レスポンスで返された各折りたたまれたヒットに対してinner_hit
リクエストごとに追加のクエリを送信することによって行われます。グループやinner_hit
リクエストが多すぎると、検索が大幅に遅くなる可能性があります。
[`````collapse`````]は[スクロール](238327401f76c2ac.md#scroll-search-results)と併用することはできません。
## search_afterによる折りたたみ
フィールドの折りたたみは、[`````search_after`````](238327401f76c2ac.md#search-after)パラメータと一緒に使用できます。`````search_after`````を使用するのは、同じフィールドでソートおよび折りたたみを行う場合のみサポートされています。二次ソートも許可されていません。たとえば、`````user.id`````で折りたたみおよびソートし、`````search_after`````を使用して結果をページングできます:
#### Python
``````python
resp = client.search(
index="my-index-000001",
query={
"match": {
"message": "GET /search"
}
},
collapse={
"field": "user.id"
},
sort=[
"user.id"
],
search_after=[
"dd5ce1ad"
],
)
print(resp)
`
Js
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
検索パラメータとともにフィールドの折りたたみを使用できます。再スコアラーは、折りたたみフィールドごとの上位ランクのドキュメントに対して各シャードで実行されます。信頼できる順序を維持するために、同じ折りたたみフィールド値を共有するドキュメントを1つのシャードにクラスタリングすることをお勧めします。これは、インデックス作成時に折りたたみフィールド値をルーティングキーとして割り当てることによって実現されます:
Python
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)
Js
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 )。 |
これにより、折りたたみキーごとに1つの上位ドキュメントのみがグローバルに再スコアリングされることが保証されます。
次のリクエストは、user.id
フィールドでフィールドの折りたたみを利用し、次にクエリ再スコアラーで上位グループを再スコアリングします:
Python
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)
Js
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
は許可されません。
Python
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)
Js
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にスコアを計算して追跡するよう指示します。