index-sorting.asciidoc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. [[index-modules-index-sorting]]
  2. == Index Sorting
  3. beta[]
  4. When creating a new index in elasticsearch it is possible to configure how the Segments
  5. inside each Shard will be sorted. By default Lucene does not apply any sort.
  6. The `index.sort.*` settings define which fields should be used to sort the documents inside each Segment.
  7. [WARNING]
  8. nested fields are not compatible with index sorting because they rely on the assumption
  9. that nested documents are stored in contiguous doc ids, which can be broken by index sorting.
  10. An error will be thrown if index sorting is activated on an index that contains nested fields.
  11. For instance the following example shows how to define a sort on a single field:
  12. [source,js]
  13. --------------------------------------------------
  14. PUT twitter
  15. {
  16. "settings" : {
  17. "index" : {
  18. "sort.field" : "date", <1>
  19. "sort.order" : "desc" <2>
  20. }
  21. },
  22. "mappings": {
  23. "tweet": {
  24. "properties": {
  25. "date": {
  26. "type": "date"
  27. }
  28. }
  29. }
  30. }
  31. }
  32. --------------------------------------------------
  33. // CONSOLE
  34. <1> This index is sorted by the `date` field
  35. <2> ... in descending order.
  36. It is also possible to sort the index by more than one field:
  37. [source,js]
  38. --------------------------------------------------
  39. PUT twitter
  40. {
  41. "settings" : {
  42. "index" : {
  43. "sort.field" : ["username", "date"], <1>
  44. "sort.order" : ["asc", "desc"] <2>
  45. }
  46. },
  47. "mappings": {
  48. "tweet": {
  49. "properties": {
  50. "username": {
  51. "type": "keyword",
  52. "doc_values": true
  53. },
  54. "date": {
  55. "type": "date"
  56. }
  57. }
  58. }
  59. }
  60. }
  61. --------------------------------------------------
  62. // CONSOLE
  63. <1> This index is sorted by `username` first then by `date`
  64. <2> ... in ascending order for the `username` field and in descending order for the `date` field.
  65. Index sorting supports the following settings:
  66. `index.sort.field`::
  67. The list of fields used to sort the index.
  68. Only `boolean`, `numeric`, `date` and `keyword` fields with `doc_values` are allowed here.
  69. `index.sort.order`::
  70. The sort order to use for each field.
  71. The order option can have the following values:
  72. * `asc`: For ascending order
  73. * `desc`: For descending order.
  74. `index.sort.mode`::
  75. Elasticsearch supports sorting by multi-valued fields.
  76. The mode option controls what value is picked to sort the document.
  77. The mode option can have the following values:
  78. * `min`: Pick the lowest value.
  79. * `max`: Pick the highest value.
  80. `index.sort.missing`::
  81. The missing parameter specifies how docs which are missing the field should be treated.
  82. The missing value can have the following values:
  83. * `_last`: Documents without value for the field are sorted last.
  84. * `_first`: Documents without value for the field are sorted first.
  85. [WARNING]
  86. Index sorting can be defined only once at index creation. It is not allowed to add or update
  87. a sort on an existing index. Index sorting also has a cost in terms of indexing throughput since
  88. documents must be sorted at flush and merge time. You should test the impact on your application
  89. before activating this feature.
  90. [float]
  91. [[early-terminate]]
  92. === Early termination of search request
  93. By default in elasticsearch a search request must visit every document that match a query to
  94. retrieve the top documents sorted by a specified sort.
  95. Though when the index sort and the search sort are the same it is possible to limit
  96. the number of documents that should be visited per segment to retrieve the N top ranked documents globally.
  97. For example, let's say we have an index that contains events sorted by a timestamp field:
  98. [source,js]
  99. --------------------------------------------------
  100. PUT events
  101. {
  102. "settings" : {
  103. "index" : {
  104. "sort.field" : "timestamp",
  105. "sort.order" : "desc" <1>
  106. }
  107. },
  108. "mappings": {
  109. "doc": {
  110. "properties": {
  111. "timestamp": {
  112. "type": "date"
  113. }
  114. }
  115. }
  116. }
  117. }
  118. --------------------------------------------------
  119. // CONSOLE
  120. <1> This index is sorted by timestamp in descending order (most recent first)
  121. You can search for the last 10 events with:
  122. [source,js]
  123. --------------------------------------------------
  124. GET /events/_search
  125. {
  126. "size": 10,
  127. "sort": [
  128. { "timestamp": "desc" }
  129. ]
  130. }
  131. --------------------------------------------------
  132. // CONSOLE
  133. // TEST[continued]
  134. Elasticsearch will detect that the top docs of each segment are already sorted in the index
  135. and will only compare the first N documents per segment.
  136. The rest of the documents matching the query are collected to count the total number of results
  137. and to build aggregations.
  138. If you're only looking for the last 10 events and have no interest in
  139. the total number of documents that match the query you can set `track_total_hits`
  140. to false:
  141. [source,js]
  142. --------------------------------------------------
  143. GET /events/_search
  144. {
  145. "size": 10,
  146. "sort": [ <1>
  147. { "timestamp": "desc" }
  148. ],
  149. "track_total_hits": false
  150. }
  151. --------------------------------------------------
  152. // CONSOLE
  153. // TEST[continued]
  154. <1> The index sort will be used to rank the top documents and each segment will early terminate the collection after the first 10 matches.
  155. This time, Elasticsearch will not try to count the number of documents and will be able to terminate the query
  156. as soon as N documents have been collected per segment.
  157. [source,js]
  158. --------------------------------------------------
  159. {
  160. "_shards": ...
  161. "hits" : {
  162. "total" : -1, <1>
  163. "max_score" : null,
  164. "hits" : []
  165. },
  166. "took": 20,
  167. "terminated_early": true, <2>
  168. "timed_out": false
  169. }
  170. --------------------------------------------------
  171. // TESTRESPONSE[s/"_shards": \.\.\./"_shards": "$body._shards",/]
  172. // TESTRESPONSE[s/"took": 20,/"took": "$body.took",/]
  173. // TESTRESPONSE[s/"terminated_early": true,//]
  174. <1> The total number of hits matching the query is unknown because of early termination.
  175. <2> Indicates whether the top docs retrieval has actually terminated_early.
  176. NOTE: Aggregations will collect all documents that match the query regardless of the value of `track_total_hits`
  177. [[index-modules-index-sorting-conjunctions]]
  178. === Use index sorting to speed up conjunctions
  179. Index sorting can be useful in order to organize Lucene doc ids (not to be
  180. conflated with `_id`) in a way that makes conjunctions (a AND b AND ...) more
  181. efficient. In order to be efficient, conjunctions rely on the fact that if any
  182. clause does not match, then the entire conjunction does not match. By using
  183. index sorting, we can put documents that do not match together, which will
  184. help skip efficiently over large ranges of doc IDs that do not match the
  185. conjunction.
  186. This trick only works with low-cardinality fields. A rule of thumb is that
  187. you should sort first on fields that both have a low cardinality and are
  188. frequently used for filtering. The sort order (`asc` or `desc`) does not
  189. matter as we only care about putting values that would match the same clauses
  190. close to each other.
  191. For instance if you were indexing cars for sale, it might be interesting to
  192. sort by fuel type, body type, make, year of registration and finally mileage.