@@ -213,7 +213,176 @@ fields ``a`` and ``b``:
213213These operations **will not** efficiently use the index ``{ a: 1, b: 1,
214214c: 1, d: 1 }`` and may not even use the index to retrieve the documents.
215215
216+ Index Sort Order
217+ ----------------
218+
219+ A collection of indexed documents may have multiple data types in the
220+ key field.
221+
222+ - When an index has a key with multiple data types, the index is
223+ sorted according to the :ref:`BSON type sort order
224+ <bson-types-comparison-order>`.
225+ - If an index key contains an array, the document is sorted according
226+ to the type of the first array element.
227+
228+ See the :ref:`index sorting example <ex-sort-index-types>`.
229+
216230Index Use and Collation
217231-----------------------
218232
219233.. include:: /includes/extracts/collation-index-use.rst
234+
235+ Examples
236+ --------
237+
238+ .. _ex-sort-index-types:
239+
240+ The following example demonstrates sorting when index keys have the
241+ same or different types.
242+
243+ Create the ``keyTypes`` collection:
244+
245+ .. code-block:: javascript
246+
247+ db.keyTypes.insertMany( [
248+ { seqNum: 1, seqType: null, type: "null" },
249+ { seqNum: 29, seqType: null, type: "null" },
250+ { seqNum: 2, seqType: Int32("10"), type: "Int32" },
251+ { seqNum: 28, seqType: Int32("10"), type: "Int32" },
252+ { seqNum: 3, seqType: Long("10"), type: "Long" },
253+ { seqNum: 27, seqType: Long("10"), type: "Long" },
254+ { seqNum: 4, seqType: Decimal128("10"), type: "Decimal128" },
255+ { seqNum: 26, seqType: Decimal128("10"), type: "Decimal128" },
256+ { seqNum: 5, seqType: Double("10"), type: "Double" },
257+ { seqNum: 25, seqType: Double("10"), type: "Double" },
258+ { seqNum: 6, seqType: String("10"), type: "String" },
259+ { seqNum: 24, seqType: String("10"), type: "String" },
260+ { seqNum: 7, seqType: [ "1", "2", "3" ], type: "Array" },
261+ { seqNum: 23, seqType: [ "1", "2", "3" ], type: "Array" },
262+ { seqNum: 8, seqType: [ [1], [2], [3] ], type: "Array" },
263+ { seqNum: 22, seqType: [ [1], [2], [3] ], type: "Array " },
264+ { seqNum: 9, seqType: [ 1, 2, 3 ], type: "Array" },
265+ { seqNum: 21, seqType: [ 1, 2, 3 ], type: "Array" },
266+ { seqNum: 10, seqType: true, type: "Boolean" },
267+ { seqNum: 11, seqType: new Timestamp(), type: "Timestamp" },
268+ { seqNum: 12, seqType: new Date(), type: "Date" },
269+ { seqNum: 13, seqType: new ObjectId(), type: "ObjectId" },
270+ ] )
271+
272+ Create indexes on the sequence number ( ``seqNum`` ) and sequence type
273+ ( ``seqType`` ) fields:
274+
275+ .. code-block:: javascript
276+
277+ db.keyTypes.createIndex( { seqNum: 1 } )
278+
279+ db.keyTypes.createIndex( { seqType: 1 } )
280+
281+
282+ Query the collection using :method:`~db.collection.find()`.
283+ The projection document, ``{ _id: 0 }``, suppresses the ``_id`` field
284+ in the output display.
285+
286+ .. code-block:: javascript
287+
288+ db.keyTypes.find( {}, { _id: 0 } )
289+
290+ The documents are returned in insertion order:
291+
292+ .. code-block:: javascript:
293+ :copyable: false
294+
295+ { seqNum: 1, seqType: null, type: 'null' },
296+ { seqNum: 29, seqType: null, type: 'null' },
297+ { seqNum: 2, seqType: 10, type: 'Int32' },
298+ { seqNum: 28, seqType: 10, type: 'Int32' },
299+ { seqNum: 3, seqType: Long("10"), type: 'Long' },
300+ { seqNum: 27, seqType: Long("10"), type: 'Long' },
301+ { seqNum: 4, seqType: Decimal128("10"), type: 'Decimal128' },
302+
303+ // Output truncated
304+
305+ The sequence number ( ``seqNum`` ) index has values of the same type.
306+ Use the ``seqNum`` index to query the ``keyTypes`` collection:
307+
308+ .. code-block:: javascript
309+
310+ db.keyTypes.find( {}, { _id: 0 } ).sort( { seqNum: 1} )
311+
312+
313+ The ``seqNum`` keys are integers. The documents are returned in
314+ numerical order:
315+
316+ .. code-block:: javascript:
317+ :copyable: false
318+
319+ { seqNum: 1, seqType: null, type: 'null' },
320+ { seqNum: 2, seqType: 10, type: 'Int32' },
321+ { seqNum: 3, seqType: Long("10"), type: 'Long' },
322+ { seqNum: 4, seqType: Decimal128("10"), type: 'Decimal128' },
323+ { seqNum: 5, seqType: 10, type: 'Double' },
324+ { seqNum: 6, seqType: '10', type: 'String' },
325+ { seqNum: 7, seqType: [ '1', '2', '3' ], type: 'Array' },
326+
327+ // Output truncated
328+
329+ The sequence type ( ``seqType`` ) index has values of the different
330+ types. Use the ``seqType`` index to query the ``keyTypes`` collection:
331+
332+ .. code-block:: javascript
333+
334+ db.keyTypes.find( {}, { _id: 0 } ).sort( { seqType: 1} )
335+
336+ The documents are returned in :ref:`BSON type sort order
337+ <bson-types-comparison-order>`:
338+
339+
340+ .. code-block:: javascript:
341+ :copyable: false
342+
343+ { seqNum: 1, seqType: null, type: 'null' },
344+ { seqNum: 29, seqType: null, type: 'null' },
345+ { seqNum: 9, seqType: [ 1, 2, 3 ], type: 'Array' },
346+ { seqNum: 21, seqType: [ 1, 2, 3 ], type: 'Array' },
347+ { seqNum: 2, seqType: 10, type: 'Int32' },
348+ { seqNum: 28, seqType: 10, type: 'Int32' },
349+ { seqNum: 3, seqType: Long("10"), type: 'Long' },
350+ { seqNum: 27, seqType: Long("10"), type: 'Long' },
351+ { seqNum: 4, seqType: Decimal128("10"), type: 'Decimal128' },
352+ { seqNum: 26, seqType: Decimal128("10"), type: 'Decimal128' },
353+ { seqNum: 5, seqType: 10, type: 'Double' },
354+ { seqNum: 25, seqType: 10, type: 'Double' },
355+ { seqNum: 7, seqType: [ '1', '2', '3' ], type: 'Array' },
356+ { seqNum: 23, seqType: [ '1', '2', '3' ], type: 'Array' },
357+ { seqNum: 6, seqType: '10', type: 'String' },
358+ { seqNum: 24, seqType: '10', type: 'String' },
359+ { seqNum: 8, seqType: [ [ 1 ], [ 2 ], [ 3 ] ], type: 'Array' },
360+ { seqNum: 22, seqType: [ [ 1 ], [ 2 ], [ 3 ] ], type: 'Array ' },
361+ {
362+ seqNum: 13,
363+ seqType: ObjectId("6239e3922604d5a7478df071"),
364+ type: 'ObjectId'
365+ },
366+ { seqNum: 10, seqType: true, type: 'Boolean' },
367+ {
368+ seqNum: 12,
369+ seqType: ISODate("2022-03-22T14:56:18.100Z"),
370+ type: 'Date'
371+ },
372+ {
373+ seqNum: 11,
374+ seqType: Timestamp({ t: 1647960978, i: 1 }),
375+ type: 'Timestamp'
376+ }
377+
378+ - Arrays are sorted according to the type of the first element. In this
379+ example the first element types are: Int32, String, and Array.
380+ - Numerical types (Int32, Long, Decimal128, Double) are equivalent when
381+ compared with other types.
382+ - Within the Numbers BSON type, numerical types are sorted:
383+
384+ - Int32
385+ - Long
386+ - Decimal128
387+ - Double
388+
0 commit comments