multivalued-fields.asciidoc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. [[esql-multivalued-fields]]
  2. === {esql} multivalued fields
  3. ++++
  4. <titleabbrev>Multivalued fields</titleabbrev>
  5. ++++
  6. {esql} is fine reading from multivalued fields:
  7. [source,console,id=esql-multivalued-fields-reorders]
  8. ----
  9. POST /mv/_bulk?refresh
  10. { "index" : {} }
  11. { "a": 1, "b": [2, 1] }
  12. { "index" : {} }
  13. { "a": 2, "b": 3 }
  14. POST /_query
  15. {
  16. "query": "FROM mv | LIMIT 2",
  17. "version": "2024.04.01"
  18. }
  19. ----
  20. Multivalued fields come back as a JSON array:
  21. [source,console-result]
  22. ----
  23. {
  24. "columns": [
  25. { "name": "a", "type": "long"},
  26. { "name": "b", "type": "long"}
  27. ],
  28. "values": [
  29. [1, [1, 2]],
  30. [2, 3]
  31. ]
  32. }
  33. ----
  34. The relative order of values in a multivalued field is undefined. They'll frequently be in
  35. ascending order but don't rely on that.
  36. [discrete]
  37. [[esql-multivalued-fields-dups]]
  38. ==== Duplicate values
  39. Some field types, like <<keyword-field-type,`keyword`>> remove duplicate values on write:
  40. [source,console,id=esql-multivalued-fields-kwdups]
  41. ----
  42. PUT /mv
  43. {
  44. "mappings": {
  45. "properties": {
  46. "b": {"type": "keyword"}
  47. }
  48. }
  49. }
  50. POST /mv/_bulk?refresh
  51. { "index" : {} }
  52. { "a": 1, "b": ["foo", "foo", "bar"] }
  53. { "index" : {} }
  54. { "a": 2, "b": ["bar", "bar"] }
  55. POST /_query
  56. {
  57. "query": "FROM mv | LIMIT 2",
  58. "version": "2024.04.01"
  59. }
  60. ----
  61. And {esql} sees that removal:
  62. [source,console-result]
  63. ----
  64. {
  65. "columns": [
  66. { "name": "a", "type": "long"},
  67. { "name": "b", "type": "keyword"}
  68. ],
  69. "values": [
  70. [1, ["bar", "foo"]],
  71. [2, "bar"]
  72. ]
  73. }
  74. ----
  75. But other types, like `long` don't remove duplicates.
  76. [source,console,id=esql-multivalued-fields-longdups]
  77. ----
  78. PUT /mv
  79. {
  80. "mappings": {
  81. "properties": {
  82. "b": {"type": "long"}
  83. }
  84. }
  85. }
  86. POST /mv/_bulk?refresh
  87. { "index" : {} }
  88. { "a": 1, "b": [2, 2, 1] }
  89. { "index" : {} }
  90. { "a": 2, "b": [1, 1] }
  91. POST /_query
  92. {
  93. "query": "FROM mv | LIMIT 2",
  94. "version": "2024.04.01"
  95. }
  96. ----
  97. And {esql} also sees that:
  98. [source,console-result]
  99. ----
  100. {
  101. "columns": [
  102. { "name": "a", "type": "long"},
  103. { "name": "b", "type": "long"}
  104. ],
  105. "values": [
  106. [1, [1, 2, 2]],
  107. [2, [1, 1]]
  108. ]
  109. }
  110. ----
  111. This is all at the storage layer. If you store duplicate `long`s and then
  112. convert them to strings the duplicates will stay:
  113. [source,console,id=esql-multivalued-fields-longdups-tostring]
  114. ----
  115. PUT /mv
  116. {
  117. "mappings": {
  118. "properties": {
  119. "b": {"type": "long"}
  120. }
  121. }
  122. }
  123. POST /mv/_bulk?refresh
  124. { "index" : {} }
  125. { "a": 1, "b": [2, 2, 1] }
  126. { "index" : {} }
  127. { "a": 2, "b": [1, 1] }
  128. POST /_query
  129. {
  130. "query": "FROM mv | EVAL b=TO_STRING(b) | LIMIT 2",
  131. "version": "2024.04.01"
  132. }
  133. ----
  134. [source,console-result]
  135. ----
  136. {
  137. "columns": [
  138. { "name": "a", "type": "long"},
  139. { "name": "b", "type": "keyword"}
  140. ],
  141. "values": [
  142. [1, ["1", "2", "2"]],
  143. [2, ["1", "1"]]
  144. ]
  145. }
  146. ----
  147. [discrete]
  148. [[esql-multivalued-fields-functions]]
  149. ==== Functions
  150. Unless otherwise documented functions will return `null` when applied to a multivalued
  151. field. This behavior may change in a later version.
  152. [source,console,id=esql-multivalued-fields-mv-into-null]
  153. ----
  154. POST /mv/_bulk?refresh
  155. { "index" : {} }
  156. { "a": 1, "b": [2, 1] }
  157. { "index" : {} }
  158. { "a": 2, "b": 3 }
  159. ----
  160. [source,console]
  161. ----
  162. POST /_query
  163. {
  164. "query": "FROM mv | EVAL b + 2, a + b | LIMIT 4",
  165. "version": "2024.04.01"
  166. }
  167. ----
  168. // TEST[continued]
  169. // TEST[warning:Line 1:16: evaluation of [b + 2] failed, treating result as null. Only first 20 failures recorded.]
  170. // TEST[warning:Line 1:16: java.lang.IllegalArgumentException: single-value function encountered multi-value]
  171. // TEST[warning:Line 1:23: evaluation of [a + b] failed, treating result as null. Only first 20 failures recorded.]
  172. // TEST[warning:Line 1:23: java.lang.IllegalArgumentException: single-value function encountered multi-value]
  173. [source,console-result]
  174. ----
  175. {
  176. "columns": [
  177. { "name": "a", "type": "long"},
  178. { "name": "b", "type": "long"},
  179. { "name": "b + 2", "type": "long"},
  180. { "name": "a + b", "type": "long"}
  181. ],
  182. "values": [
  183. [1, [1, 2], null, null],
  184. [2, 3, 5, 5]
  185. ]
  186. }
  187. ----
  188. Work around this limitation by converting the field to single value with one of:
  189. * <<esql-mv_avg>>
  190. * <<esql-mv_concat>>
  191. * <<esql-mv_count>>
  192. * <<esql-mv_max>>
  193. * <<esql-mv_median>>
  194. * <<esql-mv_min>>
  195. * <<esql-mv_sum>>
  196. [source,console,esql-multivalued-fields-mv-into-null]
  197. ----
  198. POST /_query
  199. {
  200. "query": "FROM mv | EVAL b=MV_MIN(b) | EVAL b + 2, a + b | LIMIT 4",
  201. "version": "2024.04.01"
  202. }
  203. ----
  204. // TEST[continued]
  205. [source,console-result]
  206. ----
  207. {
  208. "columns": [
  209. { "name": "a", "type": "long"},
  210. { "name": "b", "type": "long"},
  211. { "name": "b + 2", "type": "long"},
  212. { "name": "a + b", "type": "long"}
  213. ],
  214. "values": [
  215. [1, 1, 3, 2],
  216. [2, 3, 5, 5]
  217. ]
  218. }
  219. ----