multivalued-fields.asciidoc 3.9 KB

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