トップメトリクス集約

top_metrics 集約は、最も大きいまたは最も小さい「ソート」値を持つドキュメントからメトリクスを選択します。たとえば、これは s の最大値を持つドキュメントの m フィールドの値を取得します:

Python

  1. resp = client.bulk(
  2. index="test",
  3. refresh=True,
  4. operations=[
  5. {
  6. "index": {}
  7. },
  8. {
  9. "s": 1,
  10. "m": 3.1415
  11. },
  12. {
  13. "index": {}
  14. },
  15. {
  16. "s": 2,
  17. "m": 1
  18. },
  19. {
  20. "index": {}
  21. },
  22. {
  23. "s": 3,
  24. "m": 2.71828
  25. }
  26. ],
  27. )
  28. print(resp)
  29. resp1 = client.search(
  30. index="test",
  31. filter_path="aggregations",
  32. aggs={
  33. "tm": {
  34. "top_metrics": {
  35. "metrics": {
  36. "field": "m"
  37. },
  38. "sort": {
  39. "s": "desc"
  40. }
  41. }
  42. }
  43. },
  44. )
  45. print(resp1)

Ruby

  1. response = client.bulk(
  2. index: 'test',
  3. refresh: true,
  4. body: [
  5. {
  6. index: {}
  7. },
  8. {
  9. s: 1,
  10. m: 3.1415
  11. },
  12. {
  13. index: {}
  14. },
  15. {
  16. s: 2,
  17. m: 1
  18. },
  19. {
  20. index: {}
  21. },
  22. {
  23. s: 3,
  24. m: 2.71828
  25. }
  26. ]
  27. )
  28. puts response
  29. response = client.search(
  30. index: 'test',
  31. filter_path: 'aggregations',
  32. body: {
  33. aggregations: {
  34. tm: {
  35. top_metrics: {
  36. metrics: {
  37. field: 'm'
  38. },
  39. sort: {
  40. s: 'desc'
  41. }
  42. }
  43. }
  44. }
  45. }
  46. )
  47. puts response

Js

  1. const response = await client.bulk({
  2. index: "test",
  3. refresh: "true",
  4. operations: [
  5. {
  6. index: {},
  7. },
  8. {
  9. s: 1,
  10. m: 3.1415,
  11. },
  12. {
  13. index: {},
  14. },
  15. {
  16. s: 2,
  17. m: 1,
  18. },
  19. {
  20. index: {},
  21. },
  22. {
  23. s: 3,
  24. m: 2.71828,
  25. },
  26. ],
  27. });
  28. console.log(response);
  29. const response1 = await client.search({
  30. index: "test",
  31. filter_path: "aggregations",
  32. aggs: {
  33. tm: {
  34. top_metrics: {
  35. metrics: {
  36. field: "m",
  37. },
  38. sort: {
  39. s: "desc",
  40. },
  41. },
  42. },
  43. },
  44. });
  45. console.log(response1);

コンソール

  1. POST /test/_bulk?refresh
  2. {"index": {}}
  3. {"s": 1, "m": 3.1415}
  4. {"index": {}}
  5. {"s": 2, "m": 1.0}
  6. {"index": {}}
  7. {"s": 3, "m": 2.71828}
  8. POST /test/_search?filter_path=aggregations
  9. {
  10. "aggs": {
  11. "tm": {
  12. "top_metrics": {
  13. "metrics": {"field": "m"},
  14. "sort": {"s": "desc"}
  15. }
  16. }
  17. }
  18. }

どのように返されるか:

Js

  1. {
  2. "aggregations": {
  3. "tm": {
  4. "top": [ {"sort": [3], "metrics": {"m": 2.718280076980591 } } ]
  5. }
  6. }
  7. }

top_metrics は、精神的には top_hits にかなり似ていますが、より制限されているため、少ないメモリで作業を行うことができ、しばしば高速です。

ソート

メトリクスリクエストの sort フィールドは、検索 リクエストの sort フィールドとまったく同じように機能しますが、次の点を除いて:

集約が返すメトリクスは、検索リクエストによって返される最初のヒットです。したがって、

  • "sort": {"s": "desc"}
  • 最高の s を持つドキュメントからメトリクスを取得します。
  • "sort": {"s": "asc"}
  • 最低の s を持つドキュメントからメトリクスを取得します。
  • "sort": {"_geo_distance": {"location": "POINT (-78.6382 35.7796)"}}
  • 35.7796, -78.6382最も近い location を持つドキュメントからメトリクスを取得します。
  • "sort": "_score"
  • 最高のスコアを持つドキュメントからメトリクスを取得します。

メトリクス

metrics は、返す「トップ」ドキュメントのフィールドを選択します。"metrics": {"field": "m"} のように単一のメトリクスをリクエストするか、"metrics": [{"field": "m"}, {"field": "i"} のようにメトリクスのリストをリクエストすることで複数のメトリクスをリクエストできます。

metrics.field は次のフィールドタイプをサポートしています:

キーワードを除いて、対応するタイプの ランタイムフィールド もサポートされています。metrics.field配列値 を持つフィールドをサポートしていません。配列値に対する top_metric 集約は、一貫性のない結果を返す可能性があります。

次の例は、いくつかのフィールドタイプに対して top_metrics 集約を実行します。

Python

  1. resp = client.indices.create(
  2. index="test",
  3. mappings={
  4. "properties": {
  5. "d": {
  6. "type": "date"
  7. }
  8. }
  9. },
  10. )
  11. print(resp)
  12. resp1 = client.bulk(
  13. index="test",
  14. refresh=True,
  15. operations=[
  16. {
  17. "index": {}
  18. },
  19. {
  20. "s": 1,
  21. "m": 3.1415,
  22. "i": 1,
  23. "d": "2020-01-01T00:12:12Z",
  24. "t": "cat"
  25. },
  26. {
  27. "index": {}
  28. },
  29. {
  30. "s": 2,
  31. "m": 1,
  32. "i": 6,
  33. "d": "2020-01-02T00:12:12Z",
  34. "t": "dog"
  35. },
  36. {
  37. "index": {}
  38. },
  39. {
  40. "s": 3,
  41. "m": 2.71828,
  42. "i": -12,
  43. "d": "2019-12-31T00:12:12Z",
  44. "t": "chicken"
  45. }
  46. ],
  47. )
  48. print(resp1)
  49. resp2 = client.search(
  50. index="test",
  51. filter_path="aggregations",
  52. aggs={
  53. "tm": {
  54. "top_metrics": {
  55. "metrics": [
  56. {
  57. "field": "m"
  58. },
  59. {
  60. "field": "i"
  61. },
  62. {
  63. "field": "d"
  64. },
  65. {
  66. "field": "t.keyword"
  67. }
  68. ],
  69. "sort": {
  70. "s": "desc"
  71. }
  72. }
  73. }
  74. },
  75. )
  76. print(resp2)

Ruby

  1. response = client.indices.create(
  2. index: 'test',
  3. body: {
  4. mappings: {
  5. properties: {
  6. d: {
  7. type: 'date'
  8. }
  9. }
  10. }
  11. }
  12. )
  13. puts response
  14. response = client.bulk(
  15. index: 'test',
  16. refresh: true,
  17. body: [
  18. {
  19. index: {}
  20. },
  21. {
  22. s: 1,
  23. m: 3.1415,
  24. i: 1,
  25. d: '2020-01-01T00:12:12Z',
  26. t: 'cat'
  27. },
  28. {
  29. index: {}
  30. },
  31. {
  32. s: 2,
  33. m: 1,
  34. i: 6,
  35. d: '2020-01-02T00:12:12Z',
  36. t: 'dog'
  37. },
  38. {
  39. index: {}
  40. },
  41. {
  42. s: 3,
  43. m: 2.71828,
  44. i: -12,
  45. d: '2019-12-31T00:12:12Z',
  46. t: 'chicken'
  47. }
  48. ]
  49. )
  50. puts response
  51. response = client.search(
  52. index: 'test',
  53. filter_path: 'aggregations',
  54. body: {
  55. aggregations: {
  56. tm: {
  57. top_metrics: {
  58. metrics: [
  59. {
  60. field: 'm'
  61. },
  62. {
  63. field: 'i'
  64. },
  65. {
  66. field: 'd'
  67. },
  68. {
  69. field: 't.keyword'
  70. }
  71. ],
  72. sort: {
  73. s: 'desc'
  74. }
  75. }
  76. }
  77. }
  78. }
  79. )
  80. puts response

Js

  1. const response = await client.indices.create({
  2. index: "test",
  3. mappings: {
  4. properties: {
  5. d: {
  6. type: "date",
  7. },
  8. },
  9. },
  10. });
  11. console.log(response);
  12. const response1 = await client.bulk({
  13. index: "test",
  14. refresh: "true",
  15. operations: [
  16. {
  17. index: {},
  18. },
  19. {
  20. s: 1,
  21. m: 3.1415,
  22. i: 1,
  23. d: "2020-01-01T00:12:12Z",
  24. t: "cat",
  25. },
  26. {
  27. index: {},
  28. },
  29. {
  30. s: 2,
  31. m: 1,
  32. i: 6,
  33. d: "2020-01-02T00:12:12Z",
  34. t: "dog",
  35. },
  36. {
  37. index: {},
  38. },
  39. {
  40. s: 3,
  41. m: 2.71828,
  42. i: -12,
  43. d: "2019-12-31T00:12:12Z",
  44. t: "chicken",
  45. },
  46. ],
  47. });
  48. console.log(response1);
  49. const response2 = await client.search({
  50. index: "test",
  51. filter_path: "aggregations",
  52. aggs: {
  53. tm: {
  54. top_metrics: {
  55. metrics: [
  56. {
  57. field: "m",
  58. },
  59. {
  60. field: "i",
  61. },
  62. {
  63. field: "d",
  64. },
  65. {
  66. field: "t.keyword",
  67. },
  68. ],
  69. sort: {
  70. s: "desc",
  71. },
  72. },
  73. },
  74. },
  75. });
  76. console.log(response2);

コンソール

  1. PUT /test
  2. {
  3. "mappings": {
  4. "properties": {
  5. "d": {"type": "date"}
  6. }
  7. }
  8. }
  9. POST /test/_bulk?refresh
  10. {"index": {}}
  11. {"s": 1, "m": 3.1415, "i": 1, "d": "2020-01-01T00:12:12Z", "t": "cat"}
  12. {"index": {}}
  13. {"s": 2, "m": 1.0, "i": 6, "d": "2020-01-02T00:12:12Z", "t": "dog"}
  14. {"index": {}}
  15. {"s": 3, "m": 2.71828, "i": -12, "d": "2019-12-31T00:12:12Z", "t": "chicken"}
  16. POST /test/_search?filter_path=aggregations
  17. {
  18. "aggs": {
  19. "tm": {
  20. "top_metrics": {
  21. "metrics": [
  22. {"field": "m"},
  23. {"field": "i"},
  24. {"field": "d"},
  25. {"field": "t.keyword"}
  26. ],
  27. "sort": {"s": "desc"}
  28. }
  29. }
  30. }
  31. }

どのように返されるか:

Js

  1. {
  2. "aggregations": {
  3. "tm": {
  4. "top": [ {
  5. "sort": [3],
  6. "metrics": {
  7. "m": 2.718280076980591,
  8. "i": -12,
  9. "d": "2019-12-31T00:12:12.000Z",
  10. "t.keyword": "chicken"
  11. }
  12. } ]
  13. }
  14. }
  15. }

欠損

missing パラメータは、欠損値を持つドキュメントがどのように扱われるかを定義します。デフォルトでは、キーコンポーネントのいずれかが欠損している場合、ドキュメント全体が無視されます。missing パラメータを使用することで、欠損コンポーネントを値があるかのように扱うことが可能です。

Python

  1. resp = client.indices.create(
  2. index="my-index",
  3. mappings={
  4. "properties": {
  5. "nr": {
  6. "type": "integer"
  7. },
  8. "state": {
  9. "type": "keyword"
  10. }
  11. }
  12. },
  13. )
  14. print(resp)
  15. resp1 = client.bulk(
  16. index="my-index",
  17. refresh=True,
  18. operations=[
  19. {
  20. "index": {}
  21. },
  22. {
  23. "nr": 1,
  24. "state": "started"
  25. },
  26. {
  27. "index": {}
  28. },
  29. {
  30. "nr": 2,
  31. "state": "stopped"
  32. },
  33. {
  34. "index": {}
  35. },
  36. {
  37. "nr": 3,
  38. "state": "N/A"
  39. },
  40. {
  41. "index": {}
  42. },
  43. {
  44. "nr": 4
  45. }
  46. ],
  47. )
  48. print(resp1)
  49. resp2 = client.search(
  50. index="my-index",
  51. filter_path="aggregations",
  52. aggs={
  53. "my_top_metrics": {
  54. "top_metrics": {
  55. "metrics": {
  56. "field": "state",
  57. "missing": "N/A"
  58. },
  59. "sort": {
  60. "nr": "desc"
  61. }
  62. }
  63. }
  64. },
  65. )
  66. print(resp2)

Ruby

  1. response = client.indices.create(
  2. index: 'my-index',
  3. body: {
  4. mappings: {
  5. properties: {
  6. nr: {
  7. type: 'integer'
  8. },
  9. state: {
  10. type: 'keyword'
  11. }
  12. }
  13. }
  14. }
  15. )
  16. puts response
  17. response = client.bulk(
  18. index: 'my-index',
  19. refresh: true,
  20. body: [
  21. {
  22. index: {}
  23. },
  24. {
  25. nr: 1,
  26. state: 'started'
  27. },
  28. {
  29. index: {}
  30. },
  31. {
  32. nr: 2,
  33. state: 'stopped'
  34. },
  35. {
  36. index: {}
  37. },
  38. {
  39. nr: 3,
  40. state: 'N/A'
  41. },
  42. {
  43. index: {}
  44. },
  45. {
  46. nr: 4
  47. }
  48. ]
  49. )
  50. puts response
  51. response = client.search(
  52. index: 'my-index',
  53. filter_path: 'aggregations',
  54. body: {
  55. aggregations: {
  56. my_top_metrics: {
  57. top_metrics: {
  58. metrics: {
  59. field: 'state',
  60. missing: 'N/A'
  61. },
  62. sort: {
  63. nr: 'desc'
  64. }
  65. }
  66. }
  67. }
  68. }
  69. )
  70. puts response

Js

  1. const response = await client.indices.create({
  2. index: "my-index",
  3. mappings: {
  4. properties: {
  5. nr: {
  6. type: "integer",
  7. },
  8. state: {
  9. type: "keyword",
  10. },
  11. },
  12. },
  13. });
  14. console.log(response);
  15. const response1 = await client.bulk({
  16. index: "my-index",
  17. refresh: "true",
  18. operations: [
  19. {
  20. index: {},
  21. },
  22. {
  23. nr: 1,
  24. state: "started",
  25. },
  26. {
  27. index: {},
  28. },
  29. {
  30. nr: 2,
  31. state: "stopped",
  32. },
  33. {
  34. index: {},
  35. },
  36. {
  37. nr: 3,
  38. state: "N/A",
  39. },
  40. {
  41. index: {},
  42. },
  43. {
  44. nr: 4,
  45. },
  46. ],
  47. });
  48. console.log(response1);
  49. const response2 = await client.search({
  50. index: "my-index",
  51. filter_path: "aggregations",
  52. aggs: {
  53. my_top_metrics: {
  54. top_metrics: {
  55. metrics: {
  56. field: "state",
  57. missing: "N/A",
  58. },
  59. sort: {
  60. nr: "desc",
  61. },
  62. },
  63. },
  64. },
  65. });
  66. console.log(response2);

コンソール

  1. PUT /my-index
  2. {
  3. "mappings": {
  4. "properties": {
  5. "nr": { "type": "integer" },
  6. "state": { "type": "keyword" }
  7. }
  8. }
  9. }
  10. POST /my-index/_bulk?refresh
  11. {"index": {}}
  12. {"nr": 1, "state": "started"}
  13. {"index": {}}
  14. {"nr": 2, "state": "stopped"}
  15. {"index": {}}
  16. {"nr": 3, "state": "N/A"}
  17. {"index": {}}
  18. {"nr": 4}
  19. POST /my-index/_search?filter_path=aggregations
  20. {
  21. "aggs": {
  22. "my_top_metrics": {
  23. "top_metrics": {
  24. "metrics": {
  25. "field": "state",
  26. "missing": "N/A"},
  27. "sort": {"nr": "desc"}
  28. }
  29. }
  30. }
  31. }
テキストコンテンツに集約を使用する場合、それは keyword
タイプフィールドである必要があります、またはそのフィールドでフィールドデータを有効にする必要があります。
このドキュメントには欠損した state フィールド値があります。
missing パラメータは、state フィールドに欠損値がある場合、
それが N/A 値を持つかのように扱われるべきであることを定義します。

リクエストは次の応答を生成します:

コンソール-結果

  1. {
  2. "aggregations": {
  3. "my_top_metrics": {
  4. "top": [
  5. {
  6. "sort": [
  7. 4
  8. ],
  9. "metrics": {
  10. "state": "N/A"
  11. }
  12. }
  13. ]
  14. }
  15. }
  16. }

サイズ

top_metrics は、サイズパラメータを使用して、上位のいくつかのドキュメントのメトリクスを返すことができます:

Python

  1. resp = client.bulk(
  2. index="test",
  3. refresh=True,
  4. operations=[
  5. {
  6. "index": {}
  7. },
  8. {
  9. "s": 1,
  10. "m": 3.1415
  11. },
  12. {
  13. "index": {}
  14. },
  15. {
  16. "s": 2,
  17. "m": 1
  18. },
  19. {
  20. "index": {}
  21. },
  22. {
  23. "s": 3,
  24. "m": 2.71828
  25. }
  26. ],
  27. )
  28. print(resp)
  29. resp1 = client.search(
  30. index="test",
  31. filter_path="aggregations",
  32. aggs={
  33. "tm": {
  34. "top_metrics": {
  35. "metrics": {
  36. "field": "m"
  37. },
  38. "sort": {
  39. "s": "desc"
  40. },
  41. "size": 3
  42. }
  43. }
  44. },
  45. )
  46. print(resp1)

Ruby

  1. response = client.bulk(
  2. index: 'test',
  3. refresh: true,
  4. body: [
  5. {
  6. index: {}
  7. },
  8. {
  9. s: 1,
  10. m: 3.1415
  11. },
  12. {
  13. index: {}
  14. },
  15. {
  16. s: 2,
  17. m: 1
  18. },
  19. {
  20. index: {}
  21. },
  22. {
  23. s: 3,
  24. m: 2.71828
  25. }
  26. ]
  27. )
  28. puts response
  29. response = client.search(
  30. index: 'test',
  31. filter_path: 'aggregations',
  32. body: {
  33. aggregations: {
  34. tm: {
  35. top_metrics: {
  36. metrics: {
  37. field: 'm'
  38. },
  39. sort: {
  40. s: 'desc'
  41. },
  42. size: 3
  43. }
  44. }
  45. }
  46. }
  47. )
  48. puts response

Js

  1. const response = await client.bulk({
  2. index: "test",
  3. refresh: "true",
  4. operations: [
  5. {
  6. index: {},
  7. },
  8. {
  9. s: 1,
  10. m: 3.1415,
  11. },
  12. {
  13. index: {},
  14. },
  15. {
  16. s: 2,
  17. m: 1,
  18. },
  19. {
  20. index: {},
  21. },
  22. {
  23. s: 3,
  24. m: 2.71828,
  25. },
  26. ],
  27. });
  28. console.log(response);
  29. const response1 = await client.search({
  30. index: "test",
  31. filter_path: "aggregations",
  32. aggs: {
  33. tm: {
  34. top_metrics: {
  35. metrics: {
  36. field: "m",
  37. },
  38. sort: {
  39. s: "desc",
  40. },
  41. size: 3,
  42. },
  43. },
  44. },
  45. });
  46. console.log(response1);

コンソール

  1. POST /test/_bulk?refresh
  2. {"index": {}}
  3. {"s": 1, "m": 3.1415}
  4. {"index": {}}
  5. {"s": 2, "m": 1.0}
  6. {"index": {}}
  7. {"s": 3, "m": 2.71828}
  8. POST /test/_search?filter_path=aggregations
  9. {
  10. "aggs": {
  11. "tm": {
  12. "top_metrics": {
  13. "metrics": {"field": "m"},
  14. "sort": {"s": "desc"},
  15. "size": 3
  16. }
  17. }
  18. }
  19. }

どのように返されるか:

Js

  1. {
  2. "aggregations": {
  3. "tm": {
  4. "top": [
  5. {"sort": [3], "metrics": {"m": 2.718280076980591 } },
  6. {"sort": [2], "metrics": {"m": 1.0 } },
  7. {"sort": [1], "metrics": {"m": 3.1414999961853027 } }
  8. ]
  9. }
  10. }
  11. }

デフォルトの size は 1 です。最大デフォルトサイズは 10 です。集約の作業ストレージは「密」であり、各バケットに size スロットを割り当てます。10非常に 保守的なデフォルトの最大値であり、top_metrics_max_size インデックス設定を変更することで必要に応じて引き上げることができます。しかし、大きなサイズはかなりのメモリを消費する可能性があることを知っておいてください。特に、大きな 用語集約 のように多くのバケットを作成する集約の内部にある場合はそうです。引き上げたい場合は、次のようにします:

Python

  1. resp = client.indices.put_settings(
  2. index="test",
  3. settings={
  4. "top_metrics_max_size": 100
  5. },
  6. )
  7. print(resp)

Ruby

  1. response = client.indices.put_settings(
  2. index: 'test',
  3. body: {
  4. top_metrics_max_size: 100
  5. }
  6. )
  7. puts response

Js

  1. const response = await client.indices.putSettings({
  2. index: "test",
  3. settings: {
  4. top_metrics_max_size: 100,
  5. },
  6. });
  7. console.log(response);

コンソール

  1. PUT /test/_settings
  2. {
  3. "top_metrics_max_size": 100
  4. }

size1 より大きい場合、top_metrics 集約はソートの ターゲット になれません。

用語との併用

この集約は、terms 集約内で非常に便利で、たとえば、各サーバーによって報告された最後の値を見つけるために使用されるべきです。

Python

  1. resp = client.indices.create(
  2. index="node",
  3. mappings={
  4. "properties": {
  5. "ip": {
  6. "type": "ip"
  7. },
  8. "date": {
  9. "type": "date"
  10. }
  11. }
  12. },
  13. )
  14. print(resp)
  15. resp1 = client.bulk(
  16. index="node",
  17. refresh=True,
  18. operations=[
  19. {
  20. "index": {}
  21. },
  22. {
  23. "ip": "192.168.0.1",
  24. "date": "2020-01-01T01:01:01",
  25. "m": 1
  26. },
  27. {
  28. "index": {}
  29. },
  30. {
  31. "ip": "192.168.0.1",
  32. "date": "2020-01-01T02:01:01",
  33. "m": 2
  34. },
  35. {
  36. "index": {}
  37. },
  38. {
  39. "ip": "192.168.0.2",
  40. "date": "2020-01-01T02:01:01",
  41. "m": 3
  42. }
  43. ],
  44. )
  45. print(resp1)
  46. resp2 = client.search(
  47. index="node",
  48. filter_path="aggregations",
  49. aggs={
  50. "ip": {
  51. "terms": {
  52. "field": "ip"
  53. },
  54. "aggs": {
  55. "tm": {
  56. "top_metrics": {
  57. "metrics": {
  58. "field": "m"
  59. },
  60. "sort": {
  61. "date": "desc"
  62. }
  63. }
  64. }
  65. }
  66. }
  67. },
  68. )
  69. print(resp2)

Ruby

  1. response = client.indices.create(
  2. index: 'node',
  3. body: {
  4. mappings: {
  5. properties: {
  6. ip: {
  7. type: 'ip'
  8. },
  9. date: {
  10. type: 'date'
  11. }
  12. }
  13. }
  14. }
  15. )
  16. puts response
  17. response = client.bulk(
  18. index: 'node',
  19. refresh: true,
  20. body: [
  21. {
  22. index: {}
  23. },
  24. {
  25. ip: '192.168.0.1',
  26. date: '2020-01-01T01:01:01',
  27. m: 1
  28. },
  29. {
  30. index: {}
  31. },
  32. {
  33. ip: '192.168.0.1',
  34. date: '2020-01-01T02:01:01',
  35. m: 2
  36. },
  37. {
  38. index: {}
  39. },
  40. {
  41. ip: '192.168.0.2',
  42. date: '2020-01-01T02:01:01',
  43. m: 3
  44. }
  45. ]
  46. )
  47. puts response
  48. response = client.search(
  49. index: 'node',
  50. filter_path: 'aggregations',
  51. body: {
  52. aggregations: {
  53. ip: {
  54. terms: {
  55. field: 'ip'
  56. },
  57. aggregations: {
  58. tm: {
  59. top_metrics: {
  60. metrics: {
  61. field: 'm'
  62. },
  63. sort: {
  64. date: 'desc'
  65. }
  66. }
  67. }
  68. }
  69. }
  70. }
  71. }
  72. )
  73. puts response

Js

  1. const response = await client.indices.create({
  2. index: "node",
  3. mappings: {
  4. properties: {
  5. ip: {
  6. type: "ip",
  7. },
  8. date: {
  9. type: "date",
  10. },
  11. },
  12. },
  13. });
  14. console.log(response);
  15. const response1 = await client.bulk({
  16. index: "node",
  17. refresh: "true",
  18. operations: [
  19. {
  20. index: {},
  21. },
  22. {
  23. ip: "192.168.0.1",
  24. date: "2020-01-01T01:01:01",
  25. m: 1,
  26. },
  27. {
  28. index: {},
  29. },
  30. {
  31. ip: "192.168.0.1",
  32. date: "2020-01-01T02:01:01",
  33. m: 2,
  34. },
  35. {
  36. index: {},
  37. },
  38. {
  39. ip: "192.168.0.2",
  40. date: "2020-01-01T02:01:01",
  41. m: 3,
  42. },
  43. ],
  44. });
  45. console.log(response1);
  46. const response2 = await client.search({
  47. index: "node",
  48. filter_path: "aggregations",
  49. aggs: {
  50. ip: {
  51. terms: {
  52. field: "ip",
  53. },
  54. aggs: {
  55. tm: {
  56. top_metrics: {
  57. metrics: {
  58. field: "m",
  59. },
  60. sort: {
  61. date: "desc",
  62. },
  63. },
  64. },
  65. },
  66. },
  67. },
  68. });
  69. console.log(response2);

コンソール

  1. PUT /node
  2. {
  3. "mappings": {
  4. "properties": {
  5. "ip": {"type": "ip"},
  6. "date": {"type": "date"}
  7. }
  8. }
  9. }
  10. POST /node/_bulk?refresh
  11. {"index": {}}
  12. {"ip": "192.168.0.1", "date": "2020-01-01T01:01:01", "m": 1}
  13. {"index": {}}
  14. {"ip": "192.168.0.1", "date": "2020-01-01T02:01:01", "m": 2}
  15. {"index": {}}
  16. {"ip": "192.168.0.2", "date": "2020-01-01T02:01:01", "m": 3}
  17. POST /node/_search?filter_path=aggregations
  18. {
  19. "aggs": {
  20. "ip": {
  21. "terms": {
  22. "field": "ip"
  23. },
  24. "aggs": {
  25. "tm": {
  26. "top_metrics": {
  27. "metrics": {"field": "m"},
  28. "sort": {"date": "desc"}
  29. }
  30. }
  31. }
  32. }
  33. }
  34. }

どのように返されるか:

Js

  1. {
  2. "aggregations": {
  3. "ip": {
  4. "buckets": [
  5. {
  6. "key": "192.168.0.1",
  7. "doc_count": 2,
  8. "tm": {
  9. "top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 2 } } ]
  10. }
  11. },
  12. {
  13. "key": "192.168.0.2",
  14. "doc_count": 1,
  15. "tm": {
  16. "top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 3 } } ]
  17. }
  18. }
  19. ],
  20. "doc_count_error_upper_bound": 0,
  21. "sum_other_doc_count": 0
  22. }
  23. }
  24. }

top_hits とは異なり、このメトリクスの結果でバケットをソートできます:

Python

  1. resp = client.search(
  2. index="node",
  3. filter_path="aggregations",
  4. aggs={
  5. "ip": {
  6. "terms": {
  7. "field": "ip",
  8. "order": {
  9. "tm.m": "desc"
  10. }
  11. },
  12. "aggs": {
  13. "tm": {
  14. "top_metrics": {
  15. "metrics": {
  16. "field": "m"
  17. },
  18. "sort": {
  19. "date": "desc"
  20. }
  21. }
  22. }
  23. }
  24. }
  25. },
  26. )
  27. print(resp)

Ruby

  1. response = client.search(
  2. index: 'node',
  3. filter_path: 'aggregations',
  4. body: {
  5. aggregations: {
  6. ip: {
  7. terms: {
  8. field: 'ip',
  9. order: {
  10. 'tm.m' => 'desc'
  11. }
  12. },
  13. aggregations: {
  14. tm: {
  15. top_metrics: {
  16. metrics: {
  17. field: 'm'
  18. },
  19. sort: {
  20. date: 'desc'
  21. }
  22. }
  23. }
  24. }
  25. }
  26. }
  27. }
  28. )
  29. puts response

Js

  1. const response = await client.search({
  2. index: "node",
  3. filter_path: "aggregations",
  4. aggs: {
  5. ip: {
  6. terms: {
  7. field: "ip",
  8. order: {
  9. "tm.m": "desc",
  10. },
  11. },
  12. aggs: {
  13. tm: {
  14. top_metrics: {
  15. metrics: {
  16. field: "m",
  17. },
  18. sort: {
  19. date: "desc",
  20. },
  21. },
  22. },
  23. },
  24. },
  25. },
  26. });
  27. console.log(response);

コンソール

  1. POST /node/_search?filter_path=aggregations
  2. {
  3. "aggs": {
  4. "ip": {
  5. "terms": {
  6. "field": "ip",
  7. "order": {"tm.m": "desc"}
  8. },
  9. "aggs": {
  10. "tm": {
  11. "top_metrics": {
  12. "metrics": {"field": "m"},
  13. "sort": {"date": "desc"}
  14. }
  15. }
  16. }
  17. }
  18. }
  19. }

どのように返されるか:

Js

  1. {
  2. "aggregations": {
  3. "ip": {
  4. "buckets": [
  5. {
  6. "key": "192.168.0.2",
  7. "doc_count": 1,
  8. "tm": {
  9. "top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 3 } } ]
  10. }
  11. },
  12. {
  13. "key": "192.168.0.1",
  14. "doc_count": 2,
  15. "tm": {
  16. "top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 2 } } ]
  17. }
  18. }
  19. ],
  20. "doc_count_error_upper_bound": 0,
  21. "sum_other_doc_count": 0
  22. }
  23. }
  24. }

混合ソートタイプ

top_metrics を異なるインデックス間で異なるタイプを持つフィールドでソートすると、やや驚くべき結果が得られます: 浮動小数点フィールドは常に整数フィールドとは独立してソートされます。

Python

  1. resp = client.bulk(
  2. index="test",
  3. refresh=True,
  4. operations=[
  5. {
  6. "index": {
  7. "_index": "test1"
  8. }
  9. },
  10. {
  11. "s": 1,
  12. "m": 3.1415
  13. },
  14. {
  15. "index": {
  16. "_index": "test1"
  17. }
  18. },
  19. {
  20. "s": 2,
  21. "m": 1
  22. },
  23. {
  24. "index": {
  25. "_index": "test2"
  26. }
  27. },
  28. {
  29. "s": 3.1,
  30. "m": 2.71828
  31. }
  32. ],
  33. )
  34. print(resp)
  35. resp1 = client.search(
  36. index="test*",
  37. filter_path="aggregations",
  38. aggs={
  39. "tm": {
  40. "top_metrics": {
  41. "metrics": {
  42. "field": "m"
  43. },
  44. "sort": {
  45. "s": "asc"
  46. }
  47. }
  48. }
  49. },
  50. )
  51. print(resp1)

Ruby

  1. response = client.bulk(
  2. index: 'test',
  3. refresh: true,
  4. body: [
  5. {
  6. index: {
  7. _index: 'test1'
  8. }
  9. },
  10. {
  11. s: 1,
  12. m: 3.1415
  13. },
  14. {
  15. index: {
  16. _index: 'test1'
  17. }
  18. },
  19. {
  20. s: 2,
  21. m: 1
  22. },
  23. {
  24. index: {
  25. _index: 'test2'
  26. }
  27. },
  28. {
  29. s: 3.1,
  30. m: 2.71828
  31. }
  32. ]
  33. )
  34. puts response
  35. response = client.search(
  36. index: 'test*',
  37. filter_path: 'aggregations',
  38. body: {
  39. aggregations: {
  40. tm: {
  41. top_metrics: {
  42. metrics: {
  43. field: 'm'
  44. },
  45. sort: {
  46. s: 'asc'
  47. }
  48. }
  49. }
  50. }
  51. }
  52. )
  53. puts response

Js

  1. const response = await client.bulk({
  2. index: "test",
  3. refresh: "true",
  4. operations: [
  5. {
  6. index: {
  7. _index: "test1",
  8. },
  9. },
  10. {
  11. s: 1,
  12. m: 3.1415,
  13. },
  14. {
  15. index: {
  16. _index: "test1",
  17. },
  18. },
  19. {
  20. s: 2,
  21. m: 1,
  22. },
  23. {
  24. index: {
  25. _index: "test2",
  26. },
  27. },
  28. {
  29. s: 3.1,
  30. m: 2.71828,
  31. },
  32. ],
  33. });
  34. console.log(response);
  35. const response1 = await client.search({
  36. index: "test*",
  37. filter_path: "aggregations",
  38. aggs: {
  39. tm: {
  40. top_metrics: {
  41. metrics: {
  42. field: "m",
  43. },
  44. sort: {
  45. s: "asc",
  46. },
  47. },
  48. },
  49. },
  50. });
  51. console.log(response1);

コンソール

  1. POST /test/_bulk?refresh
  2. {"index": {"_index": "test1"}}
  3. {"s": 1, "m": 3.1415}
  4. {"index": {"_index": "test1"}}
  5. {"s": 2, "m": 1}
  6. {"index": {"_index": "test2"}}
  7. {"s": 3.1, "m": 2.71828}
  8. POST /test*/_search?filter_path=aggregations
  9. {
  10. "aggs": {
  11. "tm": {
  12. "top_metrics": {
  13. "metrics": {"field": "m"},
  14. "sort": {"s": "asc"}
  15. }
  16. }
  17. }
  18. }

どのように返されるか:

Js

  1. {
  2. "aggregations": {
  3. "tm": {
  4. "top": [ {"sort": [3.0999999046325684], "metrics": {"m": 2.718280076980591 } } ]
  5. }
  6. }
  7. }

これはエラーよりは良いですが、おそらく あなたが目指していたものではありません。いくつかの精度を失いますが、次のようにして整数フィールドを浮動小数点に明示的にキャストできます:

Python

  1. resp = client.search(
  2. index="test*",
  3. filter_path="aggregations",
  4. aggs={
  5. "tm": {
  6. "top_metrics": {
  7. "metrics": {
  8. "field": "m"
  9. },
  10. "sort": {
  11. "s": {
  12. "order": "asc",
  13. "numeric_type": "double"
  14. }
  15. }
  16. }
  17. }
  18. },
  19. )
  20. print(resp)

Ruby

  1. response = client.search(
  2. index: 'test*',
  3. filter_path: 'aggregations',
  4. body: {
  5. aggregations: {
  6. tm: {
  7. top_metrics: {
  8. metrics: {
  9. field: 'm'
  10. },
  11. sort: {
  12. s: {
  13. order: 'asc',
  14. numeric_type: 'double'
  15. }
  16. }
  17. }
  18. }
  19. }
  20. }
  21. )
  22. puts response

Js

  1. const response = await client.search({
  2. index: "test*",
  3. filter_path: "aggregations",
  4. aggs: {
  5. tm: {
  6. top_metrics: {
  7. metrics: {
  8. field: "m",
  9. },
  10. sort: {
  11. s: {
  12. order: "asc",
  13. numeric_type: "double",
  14. },
  15. },
  16. },
  17. },
  18. },
  19. });
  20. console.log(response);

コンソール

  1. POST /test*/_search?filter_path=aggregations
  2. {
  3. "aggs": {
  4. "tm": {
  5. "top_metrics": {
  6. "metrics": {"field": "m"},
  7. "sort": {"s": {"order": "asc", "numeric_type": "double"}}
  8. }
  9. }
  10. }
  11. }

どのように返されるか:

Js

  1. {
  2. "aggregations": {
  3. "tm": {
  4. "top": [ {"sort": [1.0], "metrics": {"m": 3.1414999961853027 } } ]
  5. }
  6. }
  7. }

パイプライン集約での使用

top_metrics は、バケットごとに単一の値を消費するパイプライン集約で使用できます。たとえば、SQLのHAVING句を使用するのと同様に、バケットフィルタリングを適用する bucket_selector です。これには、size を 1 に設定し、ラッピング集約器に渡す (単一の) メトリクスの正しいパスを指定する必要があります。たとえば:

Python

  1. resp = client.search(
  2. index="test*",
  3. filter_path="aggregations",
  4. aggs={
  5. "ip": {
  6. "terms": {
  7. "field": "ip"
  8. },
  9. "aggs": {
  10. "tm": {
  11. "top_metrics": {
  12. "metrics": {
  13. "field": "m"
  14. },
  15. "sort": {
  16. "s": "desc"
  17. },
  18. "size": 1
  19. }
  20. },
  21. "having_tm": {
  22. "bucket_selector": {
  23. "buckets_path": {
  24. "top_m": "tm[m]"
  25. },
  26. "script": "params.top_m < 1000"
  27. }
  28. }
  29. }
  30. }
  31. },
  32. )
  33. print(resp)

Ruby

  1. response = client.search(
  2. index: 'test*',
  3. filter_path: 'aggregations',
  4. body: {
  5. aggregations: {
  6. ip: {
  7. terms: {
  8. field: 'ip'
  9. },
  10. aggregations: {
  11. tm: {
  12. top_metrics: {
  13. metrics: {
  14. field: 'm'
  15. },
  16. sort: {
  17. s: 'desc'
  18. },
  19. size: 1
  20. }
  21. },
  22. having_tm: {
  23. bucket_selector: {
  24. buckets_path: {
  25. top_m: 'tm[m]'
  26. },
  27. script: 'params.top_m < 1000'
  28. }
  29. }
  30. }
  31. }
  32. }
  33. }
  34. )
  35. puts response

Js

  1. const response = await client.search({
  2. index: "test*",
  3. filter_path: "aggregations",
  4. aggs: {
  5. ip: {
  6. terms: {
  7. field: "ip",
  8. },
  9. aggs: {
  10. tm: {
  11. top_metrics: {
  12. metrics: {
  13. field: "m",
  14. },
  15. sort: {
  16. s: "desc",
  17. },
  18. size: 1,
  19. },
  20. },
  21. having_tm: {
  22. bucket_selector: {
  23. buckets_path: {
  24. top_m: "tm[m]",
  25. },
  26. script: "params.top_m < 1000",
  27. },
  28. },
  29. },
  30. },
  31. },
  32. });
  33. console.log(response);

コンソール

  1. POST /test*/_search?filter_path=aggregations
  2. {
  3. "aggs": {
  4. "ip": {
  5. "terms": {
  6. "field": "ip"
  7. },
  8. "aggs": {
  9. "tm": {
  10. "top_metrics": {
  11. "metrics": {"field": "m"},
  12. "sort": {"s": "desc"},
  13. "size": 1
  14. }
  15. },
  16. "having_tm": {
  17. "bucket_selector": {
  18. "buckets_path": {
  19. "top_m": "tm[m]"
  20. },
  21. "script": "params.top_m < 1000"
  22. }
  23. }
  24. }
  25. }
  26. }
  27. }

bucket_pathtop_metricstm と、集約値を提供するメトリクスのキーワードである m を使用します。