ES|QL マルチバリューフィールド

ES|QL はマルチバリューフィールドからの読み取りが可能です:

Python

  1. resp = client.bulk(
  2. index="mv",
  3. refresh=True,
  4. operations=[
  5. {
  6. "index": {}
  7. },
  8. {
  9. "a": 1,
  10. "b": [
  11. 2,
  12. 1
  13. ]
  14. },
  15. {
  16. "index": {}
  17. },
  18. {
  19. "a": 2,
  20. "b": 3
  21. }
  22. ],
  23. )
  24. print(resp)
  25. resp1 = client.esql.query(
  26. query="FROM mv | LIMIT 2",
  27. )
  28. print(resp1)

Js

  1. const response = await client.bulk({
  2. index: "mv",
  3. refresh: "true",
  4. operations: [
  5. {
  6. index: {},
  7. },
  8. {
  9. a: 1,
  10. b: [2, 1],
  11. },
  12. {
  13. index: {},
  14. },
  15. {
  16. a: 2,
  17. b: 3,
  18. },
  19. ],
  20. });
  21. console.log(response);
  22. const response1 = await client.esql.query({
  23. query: "FROM mv | LIMIT 2",
  24. });
  25. console.log(response1);

Console

  1. POST /mv/_bulk?refresh
  2. { "index" : {} }
  3. { "a": 1, "b": [2, 1] }
  4. { "index" : {} }
  5. { "a": 2, "b": 3 }
  6. POST /_query
  7. {
  8. "query": "FROM mv | LIMIT 2"
  9. }

マルチバリューフィールドは JSON 配列として返されます:

Console-Result

  1. {
  2. "columns": [
  3. { "name": "a", "type": "long"},
  4. { "name": "b", "type": "long"}
  5. ],
  6. "values": [
  7. [1, [1, 2]],
  8. [2, 3]
  9. ]
  10. }

マルチバリューフィールド内の値の相対的な順序は未定義です。通常は昇順になりますが、それに依存しないでください。

重複値

keyword のような一部のフィールドタイプは、書き込み時に重複値を削除します:

Python

  1. resp = client.indices.create(
  2. index="mv",
  3. mappings={
  4. "properties": {
  5. "b": {
  6. "type": "keyword"
  7. }
  8. }
  9. },
  10. )
  11. print(resp)
  12. resp1 = client.bulk(
  13. index="mv",
  14. refresh=True,
  15. operations=[
  16. {
  17. "index": {}
  18. },
  19. {
  20. "a": 1,
  21. "b": [
  22. "foo",
  23. "foo",
  24. "bar"
  25. ]
  26. },
  27. {
  28. "index": {}
  29. },
  30. {
  31. "a": 2,
  32. "b": [
  33. "bar",
  34. "bar"
  35. ]
  36. }
  37. ],
  38. )
  39. print(resp1)
  40. resp2 = client.esql.query(
  41. query="FROM mv | LIMIT 2",
  42. )
  43. print(resp2)

Js

  1. const response = await client.indices.create({
  2. index: "mv",
  3. mappings: {
  4. properties: {
  5. b: {
  6. type: "keyword",
  7. },
  8. },
  9. },
  10. });
  11. console.log(response);
  12. const response1 = await client.bulk({
  13. index: "mv",
  14. refresh: "true",
  15. operations: [
  16. {
  17. index: {},
  18. },
  19. {
  20. a: 1,
  21. b: ["foo", "foo", "bar"],
  22. },
  23. {
  24. index: {},
  25. },
  26. {
  27. a: 2,
  28. b: ["bar", "bar"],
  29. },
  30. ],
  31. });
  32. console.log(response1);
  33. const response2 = await client.esql.query({
  34. query: "FROM mv | LIMIT 2",
  35. });
  36. console.log(response2);

Console

  1. PUT /mv
  2. {
  3. "mappings": {
  4. "properties": {
  5. "b": {"type": "keyword"}
  6. }
  7. }
  8. }
  9. POST /mv/_bulk?refresh
  10. { "index" : {} }
  11. { "a": 1, "b": ["foo", "foo", "bar"] }
  12. { "index" : {} }
  13. { "a": 2, "b": ["bar", "bar"] }
  14. POST /_query
  15. {
  16. "query": "FROM mv | LIMIT 2"
  17. }

そして、ES|QL はその削除を確認します:

Console-Result

  1. {
  2. "columns": [
  3. { "name": "a", "type": "long"},
  4. { "name": "b", "type": "keyword"}
  5. ],
  6. "values": [
  7. [1, ["bar", "foo"]],
  8. [2, "bar"]
  9. ]
  10. }

しかし、long のような他のタイプは重複を削除しません。

Python

  1. resp = client.indices.create(
  2. index="mv",
  3. mappings={
  4. "properties": {
  5. "b": {
  6. "type": "long"
  7. }
  8. }
  9. },
  10. )
  11. print(resp)
  12. resp1 = client.bulk(
  13. index="mv",
  14. refresh=True,
  15. operations=[
  16. {
  17. "index": {}
  18. },
  19. {
  20. "a": 1,
  21. "b": [
  22. 2,
  23. 2,
  24. 1
  25. ]
  26. },
  27. {
  28. "index": {}
  29. },
  30. {
  31. "a": 2,
  32. "b": [
  33. 1,
  34. 1
  35. ]
  36. }
  37. ],
  38. )
  39. print(resp1)
  40. resp2 = client.esql.query(
  41. query="FROM mv | LIMIT 2",
  42. )
  43. print(resp2)

Js

  1. const response = await client.indices.create({
  2. index: "mv",
  3. mappings: {
  4. properties: {
  5. b: {
  6. type: "long",
  7. },
  8. },
  9. },
  10. });
  11. console.log(response);
  12. const response1 = await client.bulk({
  13. index: "mv",
  14. refresh: "true",
  15. operations: [
  16. {
  17. index: {},
  18. },
  19. {
  20. a: 1,
  21. b: [2, 2, 1],
  22. },
  23. {
  24. index: {},
  25. },
  26. {
  27. a: 2,
  28. b: [1, 1],
  29. },
  30. ],
  31. });
  32. console.log(response1);
  33. const response2 = await client.esql.query({
  34. query: "FROM mv | LIMIT 2",
  35. });
  36. console.log(response2);

Console

  1. PUT /mv
  2. {
  3. "mappings": {
  4. "properties": {
  5. "b": {"type": "long"}
  6. }
  7. }
  8. }
  9. POST /mv/_bulk?refresh
  10. { "index" : {} }
  11. { "a": 1, "b": [2, 2, 1] }
  12. { "index" : {} }
  13. { "a": 2, "b": [1, 1] }
  14. POST /_query
  15. {
  16. "query": "FROM mv | LIMIT 2"
  17. }

そして、ES|QL もそれを確認します:

Console-Result

  1. {
  2. "columns": [
  3. { "name": "a", "type": "long"},
  4. { "name": "b", "type": "long"}
  5. ],
  6. "values": [
  7. [1, [1, 2, 2]],
  8. [2, [1, 1]]
  9. ]
  10. }

これはすべてストレージ層でのことです。重複した long を保存し、それを文字列に変換すると、重複は残ります:

Python

  1. resp = client.indices.create(
  2. index="mv",
  3. mappings={
  4. "properties": {
  5. "b": {
  6. "type": "long"
  7. }
  8. }
  9. },
  10. )
  11. print(resp)
  12. resp1 = client.bulk(
  13. index="mv",
  14. refresh=True,
  15. operations=[
  16. {
  17. "index": {}
  18. },
  19. {
  20. "a": 1,
  21. "b": [
  22. 2,
  23. 2,
  24. 1
  25. ]
  26. },
  27. {
  28. "index": {}
  29. },
  30. {
  31. "a": 2,
  32. "b": [
  33. 1,
  34. 1
  35. ]
  36. }
  37. ],
  38. )
  39. print(resp1)
  40. resp2 = client.esql.query(
  41. query="FROM mv | EVAL b=TO_STRING(b) | LIMIT 2",
  42. )
  43. print(resp2)

Js

  1. const response = await client.indices.create({
  2. index: "mv",
  3. mappings: {
  4. properties: {
  5. b: {
  6. type: "long",
  7. },
  8. },
  9. },
  10. });
  11. console.log(response);
  12. const response1 = await client.bulk({
  13. index: "mv",
  14. refresh: "true",
  15. operations: [
  16. {
  17. index: {},
  18. },
  19. {
  20. a: 1,
  21. b: [2, 2, 1],
  22. },
  23. {
  24. index: {},
  25. },
  26. {
  27. a: 2,
  28. b: [1, 1],
  29. },
  30. ],
  31. });
  32. console.log(response1);
  33. const response2 = await client.esql.query({
  34. query: "FROM mv | EVAL b=TO_STRING(b) | LIMIT 2",
  35. });
  36. console.log(response2);

Console

  1. PUT /mv
  2. {
  3. "mappings": {
  4. "properties": {
  5. "b": {"type": "long"}
  6. }
  7. }
  8. }
  9. POST /mv/_bulk?refresh
  10. { "index" : {} }
  11. { "a": 1, "b": [2, 2, 1] }
  12. { "index" : {} }
  13. { "a": 2, "b": [1, 1] }
  14. POST /_query
  15. {
  16. "query": "FROM mv | EVAL b=TO_STRING(b) | LIMIT 2"
  17. }

Console-Result

  1. {
  2. "columns": [
  3. { "name": "a", "type": "long"},
  4. { "name": "b", "type": "keyword"}
  5. ],
  6. "values": [
  7. [1, ["1", "2", "2"]],
  8. [2, ["1", "1"]]
  9. ]
  10. }

関数

特に文書化されていない限り、関数はマルチバリューフィールドに適用されると null を返します。

Python

  1. resp = client.bulk(
  2. index="mv",
  3. refresh=True,
  4. operations=[
  5. {
  6. "index": {}
  7. },
  8. {
  9. "a": 1,
  10. "b": [
  11. 2,
  12. 1
  13. ]
  14. },
  15. {
  16. "index": {}
  17. },
  18. {
  19. "a": 2,
  20. "b": 3
  21. }
  22. ],
  23. )
  24. print(resp)

Ruby

  1. response = client.bulk(
  2. index: 'mv',
  3. refresh: true,
  4. body: [
  5. {
  6. index: {}
  7. },
  8. {
  9. a: 1,
  10. b: [
  11. 2,
  12. 1
  13. ]
  14. },
  15. {
  16. index: {}
  17. },
  18. {
  19. a: 2,
  20. b: 3
  21. }
  22. ]
  23. )
  24. puts response

Js

  1. const response = await client.bulk({
  2. index: "mv",
  3. refresh: "true",
  4. operations: [
  5. {
  6. index: {},
  7. },
  8. {
  9. a: 1,
  10. b: [2, 1],
  11. },
  12. {
  13. index: {},
  14. },
  15. {
  16. a: 2,
  17. b: 3,
  18. },
  19. ],
  20. });
  21. console.log(response);

Console

  1. POST /mv/_bulk?refresh
  2. { "index" : {} }
  3. { "a": 1, "b": [2, 1] }
  4. { "index" : {} }
  5. { "a": 2, "b": 3 }

Python

  1. resp = client.esql.query(
  2. query="FROM mv | EVAL b + 2, a + b | LIMIT 4",
  3. )
  4. print(resp)

Js

  1. const response = await client.esql.query({
  2. query: "FROM mv | EVAL b + 2, a + b | LIMIT 4",
  3. });
  4. console.log(response);

Console

  1. POST /_query
  2. {
  3. "query": "FROM mv | EVAL b + 2, a + b | LIMIT 4"
  4. }

Console-Result

  1. {
  2. "columns": [
  3. { "name": "a", "type": "long"},
  4. { "name": "b", "type": "long"},
  5. { "name": "b + 2", "type": "long"},
  6. { "name": "a + b", "type": "long"}
  7. ],
  8. "values": [
  9. [1, [1, 2], null, null],
  10. [2, 3, 5, 5]
  11. ]
  12. }

この制限を回避するには、フィールドを次のいずれかの単一値に変換します:

Python

  1. resp = client.esql.query(
  2. query="FROM mv | EVAL b=MV_MIN(b) | EVAL b + 2, a + b | LIMIT 4",
  3. )
  4. print(resp)

Js

  1. const response = await client.esql.query({
  2. query: "FROM mv | EVAL b=MV_MIN(b) | EVAL b + 2, a + b | LIMIT 4",
  3. });
  4. console.log(response);

Console

  1. POST /_query
  2. {
  3. "query": "FROM mv | EVAL b=MV_MIN(b) | EVAL b + 2, a + b | LIMIT 4"
  4. }

Console-Result

  1. {
  2. "columns": [
  3. { "name": "a", "type": "long"},
  4. { "name": "b", "type": "long"},
  5. { "name": "b + 2", "type": "long"},
  6. { "name": "a + b", "type": "long"}
  7. ],
  8. "values": [
  9. [1, 1, 3, 2],
  10. [2, 3, 5, 5]
  11. ]
  12. }