@@ -11,3 +11,332 @@ Sorts Builders
11
11
:class: singlecol
12
12
13
13
.. _sorts-builders:
14
+
15
+ Overview
16
+ --------
17
+
18
+ In this guide, we show you how to specify **sort criteria** for your
19
+ queries using **builders**.
20
+
21
+ Sort criteria are the rules MongoDB uses to sort your data. Some
22
+ examples of sort criteria are:
23
+
24
+ * Smallest number to largest number
25
+ * Earliest time of day to latest time of day
26
+ * Alphabetical order by first name
27
+
28
+ Builders are classes provided by the MongoDB Java driver that help you construct
29
+ :java-docs:`Bson <apidocs/bson/org/bson/conversions/Bson.html>` objects.
30
+ To learn more, see our :doc:`guide on builders </fundamentals/builders/>`.
31
+
32
+ You should read this guide if you would like to:
33
+
34
+ * Use builders to specify sort criteria for your queries.
35
+ * Perform ascending sorts and descending sorts.
36
+ * Combine sort criteria.
37
+ * Sort on the text score of a
38
+ :manual:`text search </core/text-search-operators/>`.
39
+
40
+ If you want to learn the fundamentals of sorting in the MongoDB Java
41
+ driver, consider reading our
42
+ :doc:`guide on sorting </fundamentals/crud/read-operations/sort/>`.
43
+
44
+ The Sorts Class
45
+ ---------------
46
+
47
+ The :java-docs:`Sorts </apidocs/mongodb-driver-core/com/mongodb/client/model/Sorts.html>`
48
+ class is a builder that provides static factory methods for all sort criteria
49
+ operators supported by MongoDB. These methods return a
50
+ :java-docs:`Bson </apidocs/bson/org/bson/conversions/Bson.html>`
51
+ object that you can pass to the
52
+ :java-docs:`sort() </apidocs/mongodb-driver-sync/com/mongodb/client/FindIterable.html#sort(org.bson.conversions.Bson)>`
53
+ method of a ``FindIterable`` instance or to
54
+ :java-docs:`Aggregates.sort() </apidocs/mongodb-driver-core/com/mongodb/client/model/Aggregates.html#sort(org.bson.conversions.Bson)>`.
55
+ If you want to learn more about ``Aggregates``, see our
56
+ :doc:`guide on the Aggregates builder </fundamentals/builders/aggregates>`.
57
+
58
+
59
+ .. _sorts-builders-sort-example:
60
+
61
+ The following examples show you how to use the methods
62
+ provided by the ``Sorts`` class to sort your queries. The examples use a
63
+ sample collection, ``sort_example``, that contains the following documents:
64
+
65
+ .. code-block:: json
66
+
67
+ {"_id": 1, "letter": "c", "food": "coffee with milk"}
68
+ {"_id": 3, "letter": "a", "food": "maple syrup"}
69
+ {"_id": 4, "letter": "b", "food": "coffee with sugar"}
70
+ {"_id": 5, "letter": "a", "food": "milk and cookies"}
71
+ {"_id": 2, "letter": "a", "food": "donuts and coffee"}
72
+ {"_id": 6, "letter": "c", "food": "maple donut"}
73
+
74
+
75
+ Sorting Direction
76
+ -----------------
77
+
78
+ The ``Sorts`` class provides methods for specifying the direction of your sort.
79
+ The direction of your sort can either be **ascending** or **descending**.
80
+ An ascending sort orders your results from smallest to largest. A
81
+ descending sort orders your results from largest to smallest.
82
+
83
+ Here are some examples of data sorted in ascending order:
84
+
85
+ * Numbers: 1, 2, 3, 43, 43, 55, 120
86
+ * Dates: 1990-03-10, 1995-01-01, 2005-10-30, 2005-12-21
87
+ * Words (ASCII): Banana, Dill, carrot, cucumber, hummus
88
+
89
+ Here are some examples of data sorted in descending order:
90
+
91
+ * Numbers: 100, 30, 12, 12, 9, 3, 1
92
+ * Dates: 2020-01-01, 1998-12-11, 1998-12-10, 1975-07-22
93
+ * Words (reverse ASCII): pear, grapes, apple, Cheese
94
+
95
+ The following subsections show how to specify these sorts using
96
+ the ``Sorts`` class.
97
+
98
+ Ascending
99
+ ~~~~~~~~~
100
+
101
+ To specify an ascending sort, use the ``Sorts.ascending()`` static
102
+ factory method. Pass ``Sorts.ascending()``
103
+ the name of the field you need to sort on.
104
+
105
+ The ``ascending()`` method can be used as follows:
106
+
107
+ .. code-block:: java
108
+
109
+ import static com.mongodb.client.model.Sorts.ascending;
110
+
111
+ // <MongoCollection setup code here>
112
+
113
+ collection.find().sort(ascending("<field name>"));
114
+
115
+ The above ``sort()`` method returns a
116
+ :java-docs:`FindIterable </apidocs/mongodb-driver-sync/com/mongodb/client/FindIterable.html>`
117
+ object containing the documents in your collection, sorted from smallest
118
+ to largest on the specified field name.
119
+
120
+ In the following code example, we use the ``ascending()`` method to sort the
121
+ :ref:`sort_example collection <sorts-builders-sort-example>`
122
+ by the ``_id`` field:
123
+
124
+ .. code-block:: java
125
+
126
+ import static com.mongodb.client.model.Sorts.ascending;
127
+
128
+ // <MongoCollection setup code here>
129
+
130
+ Bson idSort = ascending("_id");
131
+ List<Document> results = new ArrayList<>();
132
+ collection.find().sort(idSort).into(results);
133
+ for (Document result : results) {
134
+ System.out.println(result.toJson());
135
+ }
136
+
137
+ The output of the code example above should look something like this:
138
+
139
+ .. code-block:: json
140
+
141
+ {"_id": 1, "letter": "c", "food": "coffee with milk"}
142
+ {"_id": 2, "letter": "a", "food": "donuts and coffee"}
143
+ {"_id": 3, "letter": "a", "food": "maple syrup"}
144
+ ...
145
+
146
+ Descending
147
+ ~~~~~~~~~~
148
+
149
+ To specify a descending sort, use the ``Sorts.descending()`` static factory
150
+ method. Pass ``Sorts.descending()`` the name of the field you need to sort on.
151
+
152
+ The following code snippet shows how to specify a descending sort on the
153
+ ``_id`` field:
154
+
155
+ .. code-block:: java
156
+
157
+ import static com.mongodb.client.model.Sorts.descending;
158
+
159
+ // <MongoCollection setup code here>
160
+
161
+ collection.find().sort(descending("_id"));
162
+
163
+
164
+ The code snippet above returns the documents in the
165
+ :ref:`sort_example collection <sorts-builders-sort-example>`
166
+ in the following order:
167
+
168
+ .. code-block:: json
169
+
170
+ {"_id": 6, "letter": "c", "food": "maple donut"}
171
+ {"_id": 5, "letter": "a", "food": "milk and cookies"}
172
+ {"_id": 4, "letter": "b", "food": "coffee with sugar"}
173
+ ...
174
+
175
+ Handling Ties
176
+ ~~~~~~~~~~~~~
177
+
178
+ A tie occurs when two or more documents have a field with identical values.
179
+ MongoDB does not guarantee sort order in the event of ties. For example, suppose
180
+ we encounter a tie when applying a sort to the
181
+ :ref:`sort_example collection <sorts-builders-sort-example>` using the following
182
+ code:
183
+
184
+ .. code-block:: java
185
+
186
+ import static com.mongodb.client.model.Sorts.ascending;
187
+
188
+ // <MongoCollection setup code here>
189
+
190
+ collection.find().sort(ascending("letter"));
191
+
192
+ Since multiple documents contain "a" on the field we are sorting on, the first
193
+ document returned could be any of the following documents:
194
+
195
+ .. code-block:: json
196
+
197
+ {"_id": 3, "letter": "a", "food": "maple syrup"}
198
+ {"_id": 5, "letter": "a", "food": "milk and cookies"}
199
+ {"_id": 2, "letter": "a", "food": "donuts and coffee"}
200
+
201
+ If you need guaranteed sort order for documents that
202
+ have fields with identical values, you can specify additional fields to sort
203
+ on in the event of a tie.
204
+
205
+ We can specify an ascending sort on the ``letter`` field followed by the
206
+ ``_id`` field as follows:
207
+
208
+ .. code-block:: java
209
+
210
+ import static com.mongodb.client.model.Sorts.ascending;
211
+
212
+ // <MongoCollection setup code here>
213
+
214
+ collection.find().sort(ascending("letter", "_id"));
215
+
216
+ The code snippet above returns the documents in the
217
+ :ref:`sort_example collection <sorts-builders-sort-example>`
218
+ in the following order:
219
+
220
+ .. code-block:: json
221
+
222
+ {"_id": 2, "letter": "a", "food": "donuts and coffee"}
223
+ {"_id": 3, "letter": "a", "food": "maple syrup"}
224
+ {"_id": 5, "letter": "a", "food": "milk and cookies"}
225
+ {"_id": 4, "letter": "b", "food": "coffee with sugar"}
226
+ {"_id": 1, "letter": "c", "food": "coffee with milk"}
227
+ {"_id": 6, "letter": "c", "food": "maple donut"}
228
+
229
+ Combining Sort Criteria
230
+ -----------------------
231
+
232
+ To combine sort criteria, use the ``Sorts.orderBy()`` static factory
233
+ method. The ``orderBy()`` method builds sort criteria that apply passed
234
+ in sort criteria from left to right in the event of ties.
235
+
236
+ In the following code snippet, we use the ``orderBy()`` method to combine a
237
+ descending sort on the ``letter`` field with an ascending sort on the
238
+ ``_id`` field.
239
+
240
+ .. code-block:: java
241
+
242
+ import static com.mongodb.client.model.Sorts.orderBy;
243
+ import static com.mongodb.client.model.Sorts.ascending;
244
+ import static com.mongodb.client.model.Sorts.descending;
245
+
246
+ // <MongoCollection setup code here>
247
+
248
+ Bson orderBySort = orderBy(descending("letter"), ascending("_id"));
249
+ collection.find().sort(orderBySort);
250
+
251
+ The code snippet above returns the documents in the
252
+ :ref:`sort_example collection <sorts-builders-sort-example>`
253
+ in the following order:
254
+
255
+ .. code-block:: json
256
+
257
+ {"_id": 1, "letter": "c", "food": "coffee with milk"}
258
+ {"_id": 6, "letter": "c", "food": "maple donut"}
259
+ {"_id": 4, "letter": "b", "food": "coffee with sugar"}
260
+ {"_id": 2, "letter": "a", "food": "donuts and coffee"}
261
+ {"_id": 3, "letter": "a", "food": "maple syrup"}
262
+ {"_id": 5, "letter": "a", "food": "milk and cookies"}
263
+
264
+ Text Search
265
+ -----------
266
+
267
+ You can specify the order of the results of a
268
+ :manual:`text search </text-search/>` by how closely they match your
269
+ search string. Each of your search results has a
270
+ :manual:`text score </reference/operator/aggregation/meta/#exp._S_meta>`, a
271
+ numerical value indicating how well that result matches your search.
272
+ Use the ``Sorts.metaTextScore()`` static factory method to build your sort
273
+ criteria to sort by the text score.
274
+
275
+ .. warning:: Make Sure to Create a Text Index
276
+
277
+ You need a :manual:`text index </core/index-text/>` on your collection to perform a text search. See the server manual documentation for more
278
+ information on how to
279
+ :manual:`create a text index </core/index-text/#create-text-index>`.
280
+
281
+ In the following code example, we show how you can use the
282
+ ``Sorts.metaTextScore()`` method to sort the results of a text
283
+ search on the :ref:`sort_example collection <sorts-builders-sort-example>`.
284
+ The code example uses the :doc:`Filters </fundamentals/builders/filters>`,
285
+ :doc:`Indexes </fundamentals/builders/indexes>`, and
286
+ :doc:`Projections </fundamentals/builders/projections>` builders.
287
+ The code example performs the following actions:
288
+
289
+ #. Creates a text index for your
290
+ :ref:`sort_example collection <sorts-builders-sort-example>`
291
+ on the ``food`` field.
292
+ #. Runs your text search for the phrase "maple donut".
293
+ #. Projects text scores into your query results as the
294
+ ``score`` field. This projection is optional if your MongoDB instance is
295
+ running MongoDB 4.4 or later.
296
+ #. Sorts your results by text score (best match first).
297
+
298
+ .. code-block:: java
299
+
300
+ import com.mongodb.client.model.Sorts;
301
+ import com.mongodb.client.model.Projections;
302
+ import com.mongodb.client.model.Filters;
303
+ import com.mongodb.client.model.Indexes;
304
+
305
+ // <MongoCollection setup code here>
306
+
307
+ collection.createIndex(Indexes.text("food"));
308
+ Bson metaTextScoreSort = Sorts.metaTextScore("score");
309
+ Bson metaTextScoreProj = Projections.metaTextScore("score");
310
+ String searchTerm = "maple donut";
311
+ Bson searchQuery = Filters.text(searchTerm);
312
+ collection.find(searchQuery)
313
+ .projection(metaTextScoreProj)
314
+ .sort(metaTextScoreSort)
315
+ .into(results);
316
+ for (Document result : results) {
317
+ System.out.println(result.toJson());
318
+ }
319
+
320
+ The output of the code example above should look something like this:
321
+
322
+ .. code-block:: json
323
+
324
+ {"_id": 6, "letter": "c", "food": "maple donut", "score": 1.5}
325
+ {"_id": 2, "letter": "a", "food": "donuts and coffee", "score": 0.75}
326
+ {"_id": 3, "letter": "a", "food": "maple syrup", "score": 0.75}
327
+
328
+ .. note:: MongoDB 4.4 or later ``$meta`` Behavior
329
+
330
+ When using MongoDB 4.4 or later, projecting ``Projections.metaTextScore()``
331
+ into your ``FindIterable`` instance is not necessary to sort on the text
332
+ score. In addition, MongoDB 4.4 or later disregards the field name you specify
333
+ in a ``$meta`` text score aggregation operation used in a sort. This means
334
+ that the field name argument you pass to ``Sorts.metaTextScore()`` is ignored
335
+ in MongoDB 4.4 or later.
336
+
337
+ For more information, see the
338
+ :java-docs:`Sorts class API documentation </apidocs/mongodb-driver-core/com/mongodb/client/model/Sorts.html>`.
339
+ See the server manual documentation for more information on the :manual:`$text </reference/operator/query/text/>`
340
+ query operator and the
341
+ :manual:`$meta </reference/operator/aggregation/meta/>`
342
+ aggregation pipeline operator.
0 commit comments