synthetic-source.asciidoc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. [[synthetic-source]]
  2. ==== Synthetic `_source`
  3. IMPORTANT: Synthetic `_source` is Generally Available only for TSDB indices
  4. (indices that have `index.mode` set to `time_series`). For other indices,
  5. synthetic `_source` is in technical preview. Features in technical preview may
  6. be changed or removed in a future release. Elastic will work to fix
  7. any issues, but features in technical preview are not subject to the support SLA
  8. of official GA features.
  9. Though very handy to have around, the source field takes up a significant amount
  10. of space on disk. Instead of storing source documents on disk exactly as you
  11. send them, Elasticsearch can reconstruct source content on the fly upon retrieval.
  12. Enable this by using the value `synthetic` for the index setting `index.mapping.source.mode`:
  13. [source,console,id=enable-synthetic-source-example]
  14. ----
  15. PUT idx
  16. {
  17. "settings": {
  18. "index": {
  19. "mapping": {
  20. "source": {
  21. "mode": "synthetic"
  22. }
  23. }
  24. }
  25. }
  26. }
  27. ----
  28. // TESTSETUP
  29. While this on the fly reconstruction is *generally* slower than saving the source
  30. documents verbatim and loading them at query time, it saves a lot of storage
  31. space. Additional latency can be avoided by not loading `_source` field in queries when it is not needed.
  32. [[synthetic-source-fields]]
  33. ===== Supported fields
  34. Synthetic `_source` is supported by all field types. Depending on implementation details, field types have different
  35. properties when used with synthetic `_source`.
  36. <<synthetic-source-fields-native-list, Most field types>> construct synthetic `_source` using existing data, most
  37. commonly <<doc-values,`doc_values`>> and <<stored-fields, stored fields>>. For these field types, no additional space
  38. is needed to store the contents of `_source` field. Due to the storage layout of <<doc-values,`doc_values`>>, the
  39. generated `_source` field undergoes <<synthetic-source-modifications, modifications>> compared to the original document.
  40. For all other field types, the original value of the field is stored as is, in the same way as the `_source` field in
  41. non-synthetic mode. In this case there are no modifications and field data in `_source` is the same as in the original
  42. document. Similarly, malformed values of fields that use <<ignore-malformed,`ignore_malformed`>> or
  43. <<ignore-above,`ignore_above`>> need to be stored as is. This approach is less storage efficient since data needed for
  44. `_source` reconstruction is stored in addition to other data required to index the field (like `doc_values`).
  45. [[synthetic-source-restrictions]]
  46. ===== Synthetic `_source` restrictions
  47. Some field types have additional restrictions. These restrictions are documented in the **synthetic `_source`** section
  48. of the field type's <<mapping-types,documentation>>.
  49. [[synthetic-source-modifications]]
  50. ===== Synthetic `_source` modifications
  51. When synthetic `_source` is enabled, retrieved documents undergo some
  52. modifications compared to the original JSON.
  53. [[synthetic-source-modifications-leaf-arrays]]
  54. ====== Arrays moved to leaf fields
  55. Synthetic `_source` arrays are moved to leaves. For example:
  56. [source,console,id=synthetic-source-leaf-arrays-example]
  57. ----
  58. PUT idx/_doc/1
  59. {
  60. "foo": [
  61. {
  62. "bar": 1
  63. },
  64. {
  65. "bar": 2
  66. }
  67. ]
  68. }
  69. ----
  70. // TEST[s/$/\nGET idx\/_doc\/1?filter_path=_source\n/]
  71. Will become:
  72. [source,console-result]
  73. ----
  74. {
  75. "foo": {
  76. "bar": [1, 2]
  77. }
  78. }
  79. ----
  80. // TEST[s/^/{"_source":/ s/\n$/}/]
  81. This can cause some arrays to vanish:
  82. [source,console,id=synthetic-source-leaf-arrays-example-sneaky]
  83. ----
  84. PUT idx/_doc/1
  85. {
  86. "foo": [
  87. {
  88. "bar": 1
  89. },
  90. {
  91. "baz": 2
  92. }
  93. ]
  94. }
  95. ----
  96. // TEST[s/$/\nGET idx\/_doc\/1?filter_path=_source\n/]
  97. Will become:
  98. [source,console-result]
  99. ----
  100. {
  101. "foo": {
  102. "bar": 1,
  103. "baz": 2
  104. }
  105. }
  106. ----
  107. // TEST[s/^/{"_source":/ s/\n$/}/]
  108. [[synthetic-source-modifications-field-names]]
  109. ====== Fields named as they are mapped
  110. Synthetic source names fields as they are named in the mapping. When used
  111. with <<dynamic,dynamic mapping>>, fields with dots (`.`) in their names are, by
  112. default, interpreted as multiple objects, while dots in field names are
  113. preserved within objects that have <<subobjects>> disabled. For example:
  114. [source,console,id=synthetic-source-objecty-example]
  115. ----
  116. PUT idx/_doc/1
  117. {
  118. "foo.bar.baz": 1
  119. }
  120. ----
  121. // TEST[s/$/\nGET idx\/_doc\/1?filter_path=_source\n/]
  122. Will become:
  123. [source,console-result]
  124. ----
  125. {
  126. "foo": {
  127. "bar": {
  128. "baz": 1
  129. }
  130. }
  131. }
  132. ----
  133. // TEST[s/^/{"_source":/ s/\n$/}/]
  134. This impacts how source contents can be referenced in <<modules-scripting-using,scripts>>. For instance, referencing
  135. a script in its original source form will return null:
  136. [source,js]
  137. ----
  138. "script": { "source": """ emit(params._source['foo.bar.baz']) """ }
  139. ----
  140. // NOTCONSOLE
  141. Instead, source references need to be in line with the mapping structure:
  142. [source,js]
  143. ----
  144. "script": { "source": """ emit(params._source['foo']['bar']['baz']) """ }
  145. ----
  146. // NOTCONSOLE
  147. or simply
  148. [source,js]
  149. ----
  150. "script": { "source": """ emit(params._source.foo.bar.baz) """ }
  151. ----
  152. // NOTCONSOLE
  153. The following <<modules-scripting-fields, field APIs>> are preferable as, in addition to being agnostic to the
  154. mapping structure, they make use of docvalues if available and fall back to synthetic source only when needed. This
  155. reduces source synthesizing, a slow and costly operation.
  156. [source,js]
  157. ----
  158. "script": { "source": """ emit(field('foo.bar.baz').get(null)) """ }
  159. "script": { "source": """ emit($('foo.bar.baz', null)) """ }
  160. ----
  161. // NOTCONSOLE
  162. [[synthetic-source-modifications-alphabetical]]
  163. ====== Alphabetical sorting
  164. Synthetic `_source` fields are sorted alphabetically. The
  165. https://www.rfc-editor.org/rfc/rfc7159.html[JSON RFC] defines objects as
  166. "an unordered collection of zero or more name/value pairs" so applications
  167. shouldn't care but without synthetic `_source` the original ordering is
  168. preserved and some applications may, counter to the spec, do something with
  169. that ordering.
  170. [[synthetic-source-modifications-ranges]]
  171. ====== Representation of ranges
  172. Range field values (e.g. `long_range`) are always represented as inclusive on both sides with bounds adjusted
  173. accordingly. See <<range-synthetic-source-inclusive, examples>>.
  174. [[synthetic-source-precision-loss-for-point-types]]
  175. ====== Reduced precision of `geo_point` values
  176. Values of `geo_point` fields are represented in synthetic `_source` with reduced precision. See
  177. <<geo-point-synthetic-source, examples>>.
  178. [[synthetic-source-keep]]
  179. ====== Minimizing source modifications
  180. It is possible to avoid synthetic source modifications for a particular object or field, at extra storage cost.
  181. This is controlled through param `synthetic_source_keep` with the following option:
  182. - `none`: synthetic source diverges from the original source as described above (default).
  183. - `arrays`: arrays of the corresponding field or object preserve the original element ordering and duplicate elements.
  184. The synthetic source fragment for such arrays is not guaranteed to match the original source exactly, e.g. array
  185. `[1, 2, [5], [[4, [3]]], 5]` may appear as-is or in an equivalent format like `[1, 2, 5, 4, 3, 5]`. The exact format
  186. may change in the future, in an effort to reduce the storage overhead of this option.
  187. - `all`: the source for both singleton instances and arrays of the corresponding field or object gets recorded. When
  188. applied to objects, the source of all sub-objects and sub-fields gets captured. Furthermore, the original source of
  189. arrays gets captured and appears in synthetic source with no modifications.
  190. For instance:
  191. [source,console,id=create-index-with-synthetic-source-keep]
  192. ----
  193. PUT idx_keep
  194. {
  195. "settings": {
  196. "index": {
  197. "mapping": {
  198. "source": {
  199. "mode": "synthetic"
  200. }
  201. }
  202. }
  203. },
  204. "mappings": {
  205. "properties": {
  206. "path": {
  207. "type": "object",
  208. "synthetic_source_keep": "all"
  209. },
  210. "ids": {
  211. "type": "integer",
  212. "synthetic_source_keep": "arrays"
  213. }
  214. }
  215. }
  216. }
  217. ----
  218. // TEST
  219. [source,console,id=synthetic-source-keep-example]
  220. ----
  221. PUT idx_keep/_doc/1
  222. {
  223. "path": {
  224. "to": [
  225. { "foo": [3, 2, 1] },
  226. { "foo": [30, 20, 10] }
  227. ],
  228. "bar": "baz"
  229. },
  230. "ids": [ 200, 100, 300, 100 ]
  231. }
  232. ----
  233. // TEST[s/$/\nGET idx_keep\/_doc\/1?filter_path=_source\n/]
  234. returns the original source, with no array deduplication and sorting:
  235. [source,console-result]
  236. ----
  237. {
  238. "path": {
  239. "to": [
  240. { "foo": [3, 2, 1] },
  241. { "foo": [30, 20, 10] }
  242. ],
  243. "bar": "baz"
  244. },
  245. "ids": [ 200, 100, 300, 100 ]
  246. }
  247. ----
  248. // TEST[s/^/{"_source":/ s/\n$/}/]
  249. The option for capturing the source of arrays can be applied at index level, by setting
  250. `index.mapping.synthetic_source_keep` to `arrays`. This applies to all objects and fields in the index, except for
  251. the ones with explicit overrides of `synthetic_source_keep` set to `none`. In this case, the storage overhead grows
  252. with the number and sizes of arrays present in source of each document, naturally.
  253. [[synthetic-source-fields-native-list]]
  254. ===== Field types that support synthetic source with no storage overhead
  255. The following field types support synthetic source using data from <<doc-values,`doc_values`>> or
  256. <stored-fields, stored fields>>, and require no additional storage space to construct the `_source` field.
  257. NOTE: If you enable the <<ignore-malformed,`ignore_malformed`>> or <<ignore-above,`ignore_above`>> settings, then
  258. additional storage is required to store ignored field values for these types.
  259. ** <<aggregate-metric-double-synthetic-source, `aggregate_metric_double`>>
  260. ** {plugins}/mapper-annotated-text-usage.html#annotated-text-synthetic-source[`annotated-text`]
  261. ** <<binary-synthetic-source,`binary`>>
  262. ** <<boolean-synthetic-source,`boolean`>>
  263. ** <<numeric-synthetic-source,`byte`>>
  264. ** <<date-synthetic-source,`date`>>
  265. ** <<date-nanos-synthetic-source,`date_nanos`>>
  266. ** <<dense-vector-synthetic-source,`dense_vector`>>
  267. ** <<numeric-synthetic-source,`double`>>
  268. ** <<flattened-synthetic-source, `flattened`>>
  269. ** <<numeric-synthetic-source,`float`>>
  270. ** <<geo-point-synthetic-source,`geo_point`>>
  271. ** <<numeric-synthetic-source,`half_float`>>
  272. ** <<histogram-synthetic-source,`histogram`>>
  273. ** <<numeric-synthetic-source,`integer`>>
  274. ** <<ip-synthetic-source,`ip`>>
  275. ** <<keyword-synthetic-source,`keyword`>>
  276. ** <<numeric-synthetic-source,`long`>>
  277. ** <<range-synthetic-source,`range` types>>
  278. ** <<numeric-synthetic-source,`scaled_float`>>
  279. ** <<numeric-synthetic-source,`short`>>
  280. ** <<text-synthetic-source,`text`>>
  281. ** <<version-synthetic-source,`version`>>
  282. ** <<wildcard-synthetic-source,`wildcard`>>