サブオブジェクト

ドキュメントをインデックス化したりマッピングを更新したりする際、Elasticsearchは名前にドットを含むフィールドを受け入れ、それが対応するオブジェクト構造に展開されます。たとえば、フィールド metrics.time.max は、親 time オブジェクトに属する max リーフフィールドとしてマッピングされます。

説明されたデフォルトの動作はほとんどのシナリオに対して合理的ですが、たとえばフィールド metrics.time が値を保持する場合など、特定の状況では問題を引き起こします。これはメトリクスデータをインデックス化する際によく見られます。metrics.time.maxmetrics.time の両方の値を持つドキュメントは、time がリーフフィールドであり、max サブフィールドを保持するオブジェクトである必要があるため、拒否されます。

subobjects 設定は、トップレベルのマッピング定義と object フィールドにのみ適用でき、オブジェクトがさらにサブオブジェクトを保持する能力を無効にし、フィールド名にドットを含むドキュメントを保存できるようにします。上記の例から、オブジェクトコンテナ metricssubobjectsfalse に設定している場合、フィールド名にドットが保持されるため、timetime.max の両方の値を中間オブジェクトなしで直接保持できます。

Python

  1. resp = client.indices.create(
  2. index="my-index-000001",
  3. mappings={
  4. "properties": {
  5. "metrics": {
  6. "type": "object",
  7. "subobjects": False,
  8. "properties": {
  9. "time": {
  10. "type": "long"
  11. },
  12. "time.min": {
  13. "type": "long"
  14. },
  15. "time.max": {
  16. "type": "long"
  17. }
  18. }
  19. }
  20. }
  21. },
  22. )
  23. print(resp)
  24. resp1 = client.index(
  25. index="my-index-000001",
  26. id="metric_1",
  27. document={
  28. "metrics.time": 100,
  29. "metrics.time.min": 10,
  30. "metrics.time.max": 900
  31. },
  32. )
  33. print(resp1)
  34. resp2 = client.index(
  35. index="my-index-000001",
  36. id="metric_2",
  37. document={
  38. "metrics": {
  39. "time": 100,
  40. "time.min": 10,
  41. "time.max": 900
  42. }
  43. },
  44. )
  45. print(resp2)
  46. resp3 = client.indices.get_mapping(
  47. index="my-index-000001",
  48. )
  49. print(resp3)

Ruby

  1. response = client.indices.create(
  2. index: 'my-index-000001',
  3. body: {
  4. mappings: {
  5. properties: {
  6. metrics: {
  7. type: 'object',
  8. subobjects: false,
  9. properties: {
  10. time: {
  11. type: 'long'
  12. },
  13. 'time.min' => {
  14. type: 'long'
  15. },
  16. 'time.max' => {
  17. type: 'long'
  18. }
  19. }
  20. }
  21. }
  22. }
  23. }
  24. )
  25. puts response
  26. response = client.index(
  27. index: 'my-index-000001',
  28. id: 'metric_1',
  29. body: {
  30. 'metrics.time' => 100,
  31. 'metrics.time.min' => 10,
  32. 'metrics.time.max' => 900
  33. }
  34. )
  35. puts response
  36. response = client.index(
  37. index: 'my-index-000001',
  38. id: 'metric_2',
  39. body: {
  40. metrics: {
  41. time: 100,
  42. 'time.min' => 10,
  43. 'time.max' => 900
  44. }
  45. }
  46. )
  47. puts response
  48. response = client.indices.get_mapping(
  49. index: 'my-index-000001'
  50. )
  51. puts response

Js

  1. const response = await client.indices.create({
  2. index: "my-index-000001",
  3. mappings: {
  4. properties: {
  5. metrics: {
  6. type: "object",
  7. subobjects: false,
  8. properties: {
  9. time: {
  10. type: "long",
  11. },
  12. "time.min": {
  13. type: "long",
  14. },
  15. "time.max": {
  16. type: "long",
  17. },
  18. },
  19. },
  20. },
  21. },
  22. });
  23. console.log(response);
  24. const response1 = await client.index({
  25. index: "my-index-000001",
  26. id: "metric_1",
  27. document: {
  28. "metrics.time": 100,
  29. "metrics.time.min": 10,
  30. "metrics.time.max": 900,
  31. },
  32. });
  33. console.log(response1);
  34. const response2 = await client.index({
  35. index: "my-index-000001",
  36. id: "metric_2",
  37. document: {
  38. metrics: {
  39. time: 100,
  40. "time.min": 10,
  41. "time.max": 900,
  42. },
  43. },
  44. });
  45. console.log(response2);
  46. const response3 = await client.indices.getMapping({
  47. index: "my-index-000001",
  48. });
  49. console.log(response3);

コンソール

  1. PUT my-index-000001
  2. {
  3. "mappings": {
  4. "properties": {
  5. "metrics": {
  6. "type": "object",
  7. "subobjects": false,
  8. "properties": {
  9. "time": { "type": "long" },
  10. "time.min": { "type": "long" },
  11. "time.max": { "type": "long" }
  12. }
  13. }
  14. }
  15. }
  16. }
  17. PUT my-index-000001/_doc/metric_1
  18. {
  19. "metrics.time" : 100,
  20. "metrics.time.min" : 10,
  21. "metrics.time.max" : 900
  22. }
  23. PUT my-index-000001/_doc/metric_2
  24. {
  25. "metrics" : {
  26. "time" : 100,
  27. "time.min" : 10,
  28. "time.max" : 900
  29. }
  30. }
  31. GET my-index-000001/_mapping

コンソール結果

  1. {
  2. "my-index-000001" : {
  3. "mappings" : {
  4. "properties" : {
  5. "metrics" : {
  6. "subobjects" : false,
  7. "properties" : {
  8. "time" : {
  9. "type" : "long"
  10. },
  11. "time.min" : {
  12. "type" : "long"
  13. },
  14. "time.max" : {
  15. "type" : "long"
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }
metrics フィールドは他のオブジェクトを保持できません。
フラットパスを保持するサンプルドキュメント
サブオブジェクトを保持しないように構成されたオブジェクトとそのリーフサブフィールドを保持するサンプルドキュメント
フィールド名のドットが保持された結果のマッピング

全体のマッピングもサブオブジェクトをサポートしないように構成でき、その場合、ドキュメントはリーフサブフィールドのみを保持できます:

Python

  1. resp = client.indices.create(
  2. index="my-index-000001",
  3. mappings={
  4. "subobjects": False
  5. },
  6. )
  7. print(resp)
  8. resp1 = client.index(
  9. index="my-index-000001",
  10. id="metric_1",
  11. document={
  12. "time": "100ms",
  13. "time.min": "10ms",
  14. "time.max": "900ms"
  15. },
  16. )
  17. print(resp1)

Ruby

  1. response = client.indices.create(
  2. index: 'my-index-000001',
  3. body: {
  4. mappings: {
  5. subobjects: false
  6. }
  7. }
  8. )
  9. puts response
  10. response = client.index(
  11. index: 'my-index-000001',
  12. id: 'metric_1',
  13. body: {
  14. time: '100ms',
  15. 'time.min' => '10ms',
  16. 'time.max' => '900ms'
  17. }
  18. )
  19. puts response

Js

  1. const response = await client.indices.create({
  2. index: "my-index-000001",
  3. mappings: {
  4. subobjects: false,
  5. },
  6. });
  7. console.log(response);
  8. const response1 = await client.index({
  9. index: "my-index-000001",
  10. id: "metric_1",
  11. document: {
  12. time: "100ms",
  13. "time.min": "10ms",
  14. "time.max": "900ms",
  15. },
  16. });
  17. console.log(response1);

コンソール

  1. PUT my-index-000001
  2. {
  3. "mappings": {
  4. "subobjects": false
  5. }
  6. }
  7. PUT my-index-000001/_doc/metric_1
  8. {
  9. "time" : "100ms",
  10. "time.min" : "10ms",
  11. "time.max" : "900ms"
  12. }
全体のマッピングはオブジェクトをサポートしないように構成されています。
ドキュメントはオブジェクトをサポートしていません

既存のフィールドとトップレベルのマッピング定義に対する subobjects 設定は更新できません。

自動フラット化オブジェクトマッピング

一般的に、subobjects: false で構成されたオブジェクトのプロパティをドット付きフィールド名で定義することが推奨されます(最初の例に示されています)。ただし、これらのプロパティをマッピング内のサブオブジェクトとして定義することも可能です。その場合、マッピングは保存される前に自動的にフラット化されます。これにより、既存のマッピングを再利用する際に再記述する必要がなくなります。

自動フラット化は、subobjects: false で構成されたオブジェクトの下に定義されたオブジェクトマッピングに特定の マッピングパラメータ が設定されている場合には機能しないことに注意してください:

  • enabled マッピングパラメータは false であってはなりません。
  • dynamic マッピングパラメータは、親の暗黙的または明示的な値と矛盾してはなりません。たとえば、マッピングのルートで dynamicfalse に設定されている場合、dynamictrue に設定するオブジェクトマッパーは自動フラット化できません。
  • subobjects マッピングパラメータは true に明示的に設定されてはなりません。

Python

  1. resp = client.indices.create(
  2. index="my-index-000002",
  3. mappings={
  4. "properties": {
  5. "metrics": {
  6. "subobjects": False,
  7. "properties": {
  8. "time": {
  9. "type": "object",
  10. "properties": {
  11. "min": {
  12. "type": "long"
  13. },
  14. "max": {
  15. "type": "long"
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }
  22. },
  23. )
  24. print(resp)
  25. resp1 = client.indices.get_mapping(
  26. index="my-index-000002",
  27. )
  28. print(resp1)

Ruby

  1. response = client.indices.create(
  2. index: 'my-index-000002',
  3. body: {
  4. mappings: {
  5. properties: {
  6. metrics: {
  7. subobjects: false,
  8. properties: {
  9. time: {
  10. type: 'object',
  11. properties: {
  12. min: {
  13. type: 'long'
  14. },
  15. max: {
  16. type: 'long'
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }
  23. }
  24. }
  25. )
  26. puts response
  27. response = client.indices.get_mapping(
  28. index: 'my-index-000002'
  29. )
  30. puts response

コンソール

  1. PUT my-index-000002
  2. {
  3. "mappings": {
  4. "properties": {
  5. "metrics": {
  6. "subobjects": false,
  7. "properties": {
  8. "time": {
  9. "type": "object",
  10. "properties": {
  11. "min": { "type": "long" },
  12. "max": { "type": "long" }
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }
  19. }
  20. GET my-index-000002/_mapping

コンソール結果

  1. {
  2. "my-index-000002" : {
  3. "mappings" : {
  4. "properties" : {
  5. "metrics" : {
  6. "subobjects" : false,
  7. "properties" : {
  8. "time.min" : {
  9. "type" : "long"
  10. },
  11. "time.max" : {
  12. "type" : "long"
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }
  19. }
メトリクスオブジェクトは、さらにオブジェクトマッピングを含むことができ、自動的にフラット化されます。
オブジェクトマッピングは、このレベルで上記のように特定のマッピングパラメータを設定してはなりません。
このフィールドは、マッピングが保存される前に "time.min" に自動的にフラット化されます。
自動フラット化された "time.min" フィールドは、インデックスマッピングを確認することで検査できます。