Overview
MongoDB Search allows you to sort the results in ascending or descending order on fields that you define in your MongoDB Search index. You can sort by the following field types using the sort option:
booleandatenumber(integer, float, and double values)objectIduuidstring(indexed as the token type)
You can also sort by the score of the documents in the results and by null values.
sort Option Compatibility
Atlas supports both non-sharded and sharded sort queries on all major and minor releases for MongoDB 7.0 and later versions.
sort Option Limitations
You can't sort on fields of embeddedDocuments type.
You can't use the
sortoption with the deprecated knnBeta operator.
Usage
To sort your MongoDB Search results, you must do the following:
Create a MongoDB Search index on the fields to sort the results by.
To sort on
boolean,date,number,UUID, andobjectIdfields, use dynamic or static mappings. To sort on string fields, you must use static mappings to index the field as thetokentype.Create and run your query with the
sortoption against the fields you defined in the index for sorting. To learn more, see Syntax.
Behavior
Sort by Boolean, Date, Numeric, UUID, ObjectId, or String Field
The sort option takes a document that specifies the fields to sort by and the respective sort order. MongoDB Search follows the MongoDB comparison order for the supported data types. It treats UUID values like BinData. To learn more, see non-existent fields.
You can specify the following sort order to sort your results by:
| Sort in ascending order. When you sort in ascending order, MongoDB Search returns documents with missing values before documents with values. |
| Sort in descending order. |
Sort by Score And a Unique Field
You can also sort by score in ascending or descending order. The sort option takes a document that specifies the $meta expression, which requires the searchScore value.
Example
Suppose your application allows users to skip to the last page of the search results. The following example sorts the results by score in ascending order so that the document with the lowest score displays at the top of the results:
sort: {score: {$meta: "searchScore", order: 1}}
You can use sort to also ensure that the results have a determined order when multiple documents in the results have identical scores. For example, if you sort the results by a unique field, such as a date field named lastUpdated as shown in the following example, MongoDB Search returns results with identical scores in a determined order:
Example
sort: {score: {$meta: "searchScore"}, lastUpdated: 1}
However, if you don't specify a unique field to sort the results by, MongoDB Search returns the results sorted by score in descending order. MongoDB Search returns results with identical scores or values in an arbitrary order. The following example doesn't sort the results by a unique field.
Example
sort: {score: {$meta: "searchScore"}}
To learn more, see Score the Documents in the Results.
Sort Arrays
MongoDB Search flattens the arrays for sorting.
Example
Consider the following array:
[4, [1, [8,5], 9], 2]
MongoDB Search flattens the preceding array similar to the following:
4, 1, 8, 5, 9, 2
For an ascending sort, MongoDB Search uses 1 to compare the array to other values. For a descending sort, MongoDB Search uses 9 to compare the array to other values.
When comparing with elements inside an array:
For an ascending sort, MongoDB Search compares the smallest elements of the array or performs a less than (
<) comparison.Example
MongoDB Search sorts results in the following order if you sort by numbers in ascending order:
-20 [-3, 12] // <- -3 comes before 5. 5 [6, 18] // <- 6 comes after 5. 13 14 For a descending sort, MongoDB Search compares the largest elements of the array or performs a greater than (
>) comparison.Example
MongoDB Search sorts results in the following order if you sort by numbers in descending order:
[6, 18] // <- 18 comes before 14. 14 13 [-3, 12] // <- 12 comes after 13. 5 -20
Sort Arrays with Multiple Types
When sorting over array fields that contain values of multiple BSON types, MongoDB Search selects a representative element from the array to use for comparison according to the MongoDB comparison and sort order by default.
For an ascending sort, MongoDB Search uses the element with the lowest BSON type.
For a descending sort, MongoDB Search uses the element with the highest BSON type.
If there are multiple values of the same BSON type in the array, standard sort behavior for the selected type applies.
Example
Consider the following array:
[ 'foo', null, 15, true, false ]
For an ascending sort, MongoDB Search uses
null, as it is the lowest supported BSON type.For a descending sort, MongoDB Search uses
true, as it is the highest BSON type in the array and MongoDB Search rankstruevalues abovefalsevalues.
However, if you set noData: highest in your sort syntax, MongoDB Search considers null and missing values as the highest BSON type. For the example array, the following behavior applies:
For an ascending sort, MongoDB Search uses
15, as it is now the lowest BSON type in the array.For a descending sort, MongoDB Search uses
null, as it is now the highest BSON type in the array.
To learn more, see Sort by Null and Missing Values.
For an example, see Sort on Multi-Typed Arrays.
Sort by Null and Missing Values
MongoDB Search treats null values as equal to missing and empty values, and the order of documents with these values is non-deterministic when sorting.
By default, MongoDB Search follows the MongoDB comparison and sort order and considers null values as lower than all other supported BSON types. Therefore, null values appear at the top of the results during an ascending sort and at the bottom during a descending sort.
To configure where null values appear in the results, specify the noData field in your sort syntax. The noData field takes the following values:
lowest(default): Sets null values as the lowest BSON type during sorting. Sorts null values at the top of the results during an ascending sort and at the bottom during a descending sort.highest: Sets null values as the highest BSON type during sorting. Sorts null values at the bottom of the results during an ascending sort and at the top during a descending sort.
Note
The same behavior applies when sorting on arrays with multiple types that contain null or missing values.
For examples, see Sort by Null Values and Sort on Multi-Typed Arrays.
Sort on Embedded Documents Array Fields
To sort the parent documents by an embedded document field, you must do the following:
Index the parents of the embedded document child field as the document type.
Index the child field with string values within the embedded document as the token type. For child fields with number and date values, enable dynamic mapping to index those fields automatically.
MongoDB Search sorts on parent documents only. It doesn't sort the child fields within an array of documents. For an example, see Sort Example.
Considerations
Consistency
MongoDB Search indexes are eventually consistent, and values returned in results might be different from values used in sorting.
Performance
This feature optimizes queries that use $search with $limit as a subsequent stage. If MongoDB Search needs to sort all documents in the collection, the response might be slow.
Scoring
MongoDB Search returns scores for all documents in the results. However, you might see higher scoring documents after lower scoring documents because the order of documents in the results is based on the sort criteria unless you explicitly sort by score.
Syntax
sort has the following syntax:
1 { 2 "$search": { 3 "index": "<index name>", // optional, defaults to "default" 4 "<operator>": { // such as "text", "compound", or "phrase" 5 <operator-specification> 6 }, 7 "sort": { 8 score: {$meta: "searchScore"}, // optional field 9 "<field-to-sort>": <sort-order>, // 1 or -1, or a document 10 ... 11 } 12 } 13 }
Parameter | Description | |||||
|---|---|---|---|---|---|---|
| Optional. Determines whether to sort by the search score. To learn more, see Sort by Score And a Unique Field. | |||||
| Required. The name of the field to sort by. | |||||
| Required. Determines the sort order. Use If you want to specify the noData field, use a document with the following syntax: |
Examples
The following examples use the sample_mflix.movies, sample_airbnb.listingsAndReview, or a custom collection named users.
Index Definition
The example queries in this page use either the sample_mflix.movies, the sample_airbnb.listingsAndReview, or a custom collection. If you create the following indexes on these collections, you can run the sample queries against the indexed fields.
The index definition for the movies collection specifies the following:
Index
awards.winsfield as:numbertype for sorting and querying, including runningfacet(MongoDB Search Operator) queries
Index
releasedfield as:datetype for sorting and querying, including runningfacet(MongoDB Search Operator) queries
Index
titlefield as:tokentype for sortingstringtype for querying
1 { 2 "mappings": { 3 "dynamic": true, 4 "fields": { 5 "awards": { 6 "dynamic": false, 7 "fields": { 8 "wins": [ 9 { 10 "type": "number" 11 } 12 ] 13 }, 14 "type": "document" 15 }, 16 "released": [ 17 { 18 "type": "date" 19 } 20 ], 21 "title": [{ 22 "type": "token" 23 }, { 24 "type": "string" 25 }] 26 } 27 } 28 }
For the preceding index definition, MongoDB Search creates an index named default with static mappings on the specified fields.
The example queries against the sample_airbnb.listingsAndReviews collection use the following index. The index definition specifies dynamic mappings on the fields in the collection:
{ "mappings": { "dynamic": true } }
The users collection contains the following documents:
db.users.insertMany([ { "_id": 0, "a": UUID("1a324de2-e34b-c87e-f2a1-42ce37ad74ed"), "b": "hello", "c": ObjectId("507f1f77bcf86cd799439011") }, { "_id": 1, "a": UUID("3b241101-e2bb-4255-8caf-4136c566a962"), "b": "hello", "c": true }, { "_id": 2, "a": UUID("dee11d4e-63c6-4d90-983c-5c9f1e79e96c"), "b": "hello", "c": "foo" }, { "_id": 3, "b": "hello", "c": UUID("3be11d4e-62cb-4e95-9a3c-5c9f1e56c732") }, { "_id": 4, "a": UUID("d3c12e1c-c36e-25ed-7c3e-1e7f1e53c752"), "b": "hello", "c": null }, { "_id": 5, "a": UUID("d73f181e-cdda-42b4-b844-4d6e172e9bc8"), "b": "hello", "c": [] } { "_id": 6, "a": UUID("7eeddf21-b313-4a5c-81c2-c68915daa618"), "b": "hello", } ])
The index definition for the users collection specifies the following:
Dynamically index all the fields except fields named
c.Statically index field named
cas the following types for sorting:tokenuuidobjectIdboolean
1 { 2 "mappings": { 3 "dynamic": true, 4 "fields": { 5 "c": [ 6 { "type": "token" }, 7 { "type": "uuid" }, 8 { "type": "objectId" }, 9 { "type": "boolean" }, 10 { "type": "number" } 11 ] 12 } 13 } 14 }
For the preceding collection, MongoDB Search creates an index named default with the specified mappings on the specified fields.
Date Search and Sort
The following query shows how to run a compound operator query and sort the results by a date field. It uses the following operators:
wildcard operator to search for movie titles that begin with
Summer.near operator to search for movies that were released in and about five months before or after April 18, 2014.
Note
When you use
pivoton a date field, its unit of measure is in milliseconds. MongoDB Search calculates a score for each document based on how close the date field is to the specified date. To learn more, see near.
The query uses the following pipeline stages:
Number Search and Sort
The following query shows how to sort the results by a numeric field. It uses the range operator to search for movies that have won 10 or more awards and then sorts the results by the numeric field value in descending order.
The query uses the following pipeline stages:
String Search and Sort
Basic Example
The following query on the sample_mflix.movies namespace uses the $search stage to do the following:
Search for movies that have the term
countryin the title.Sort the results in ascending order using
sortoption.
The query uses the $limit stage to limit the output to 5 documents. It also uses the $project stage to do the following:
Omit all fields except
titlein the results.Add a field named
score.
db.movies.aggregate([ { "$search": { "text": { "path": "title", "query": "country" }, "sort": { "title": 1 } } }, { "$limit": 5 }, { "$project": { "_id": 0, "title": 1, "score": { "$meta": "searchScore" } } } ])
[ { title: 'A Country Called Home', score: 2.536633253097534 }, { title: 'A Month in the Country', score: 2.258953094482422 }, { title: 'A Quiet Place in the Country', score: 2.0360684394836426 }, { title: 'A Sunday in the Country', score: 2.258953094482422 }, { title: 'Another Country', score: 3.3635599613189697 } ]
Compound Wildcard Search and Sort Example
The following query shows how to query and sort the results by a string field. It searches for titles that begin with Prance or Prince and sorts the results by the title field in ascending order.
The query uses the following pipeline stages:
Cases-Insensitive Sort Example
The following query shows how to sort the results regardless of the letter case. It uses the text operator to search for movies that have the term train in the title field and then sorts the results by the title field value in ascending order.
The query specifies a $limit stage to limit the documents in the results to 5 and a $project stage to do the following:
Include only the
_id,title, andawardsfields in the results.Add a field named score in the results.
Sort by ObjectId
The following query uses the range operator to search the the released field in the sample_mflix.movies collection for movies released between 2015-01-01 and 2015-12-31. It sorts the results by the _id field, which contains value of type ObjectId, in descending order.
db.movies.aggregate([ { "$search": { "range": { "path": "released", "gt": ISODate("2015-01-01T00:00:00.000Z"), "lt": ISODate("2015-12-31T00:00:00.000Z") }, "sort": { "_id": -1 } } }, { "$limit": 5 }, { "$project": { "_id": 1, "title": 1, "released": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: ObjectId('573a13fbf29313caabdedf31'), title: 'No Home Movie', released: ISODate('2015-08-10T00:00:00.000Z'), score: 1 }, { _id: ObjectId('573a13fbf29313caabdedf30'), title: 'Our Loved Ones', released: ISODate('2015-08-12T00:00:00.000Z'), score: 1 }, { _id: ObjectId('573a13faf29313caabded406'), title: 'The Red Spider', released: ISODate('2015-11-20T00:00:00.000Z'), score: 1 }, { _id: ObjectId('573a13faf29313caabded1d6'), title: 'The Laundryman', released: ISODate('2015-07-11T00:00:00.000Z'), score: 1 }, { _id: ObjectId('573a13faf29313caabdecaf3'), title: 'Right Now, Wrong Then', released: ISODate('2015-09-01T00:00:00.000Z'), score: 1 } ]
Sort by UUID
The following query searches for the term hello in field b in the users collection. The query sorts the results by field a, which contains polymorphic data (to demonstrate the sort order), in ascending order.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "a": 1 } } }, { "$project": { "_id": 1, "a": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 3, score: 0.029335692524909973 }, { _id: 0, a: UUID('1a324de2-e34b-c87e-f2a1-42ce37ad74ed'), score: 0.029335692524909973 }, { _id: 1, a: UUID('3b241101-e2bb-4255-8caf-4136c566a962'), score: 0.029335692524909973 }, { _id: 6, a: UUID('7eeddf21-b313-4a5c-81c2-c68915daa618'), score: 0.029335692524909973 }, { _id: 4, a: UUID('d3c12e1c-c36e-25ed-7c3e-1e7f1e53c752'), score: 0.029335692524909973 }, { _id: 5, a: UUID('d73f181e-cdda-42b4-b844-4d6e172e9bc8'), score: 0.029335692524909973 }, { _id: 2, a: UUID('dee11d4e-63c6-4d90-983c-5c9f1e79e96c'), score: 0.029335692524909973 } ]
Sort by Null Values
Consider the following queries that search field b for the string hello in the users collection using the text operator. The query then sorts the results by field c, which contains null or missing values for some documents in the collection.
To learn more, see Sort by Null and Missing Values.
During an ascending sort, MongoDB Search returns documents with null or missing values at the top of the results by default, as shown in the following example:
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": 1 } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 4, c: null, score: 0.029335692524909973 }, { _id: 5, c: [], score: 0.029335692524909973 }, { _id: 6, score: 0.029335692524909973 }, { _id: 2, c: 'foo', score: 0.029335692524909973 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.029335692524909973 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.029335692524909973 }, { _id: 1, c: true, score: 0.029335692524909973 } ]
During a descending sort, MongoDB Search returns documents with null or missing values at the bottom of the results by default, as shown in the following example:
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": -1 } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 1, c: true, score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 2, c: 'foo', score: 0.025981096550822258 }, { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 } ]
Note
Setting noData: lowest is the same as the default.
If you specify the noData field as lowest during an ascending sort, MongoDB Search returns documents with null or missing values at the top of the results, as shown in the following example.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": { "order": 1, "noData": "lowest" } } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 4, c: null, score: 0.029335692524909973 }, { _id: 5, c: [], score: 0.029335692524909973 }, { _id: 6, score: 0.029335692524909973 }, { _id: 2, c: 'foo', score: 0.029335692524909973 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.029335692524909973 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.029335692524909973 }, { _id: 1, c: true, score: 0.029335692524909973 } ]
If you specify the noData field as lowest during a descending sort, MongoDB Search returns documents with null or missing values at the bottom of the results, as shown in the following example.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": { "order": -1, "noData": "lowest" } } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 1, c: true, score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 2, c: 'foo', score: 0.025981096550822258 }, { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 } ]
If you specify the noData field as highest during an ascending sort, MongoDB Search returns documents with null or missing values at the bottom of the results, as shown in the following example.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": { "order": 1, "noData": "highest" } } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 2, c: 'foo', score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 1, c: true, score: 0.025981096550822258 }, { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 } ]
If you specify the noData field as highest during a descending sort, MongoDB Search returns documents with null or missing values at the top of the results, as shown in the following example.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": { "order": -1, "noData": "highest" } } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 }, { _id: 1, c: true, score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 2, c: 'foo', score: 0.025981096550822258 } ]
The order of documents with "_id": 4, "_id": 5, and "_id": 6 is random because MongoDB Search treats null and missing values as equal when sorting.
Sort on Multi-Typed Arrays
Consider the following queries on the users collection given an additional document with a multi-typed array in field c:
db.users.insertOne({ "_id": 7, "a": UUID("03e32aa9-1cbd-43b8-b9d6-18b171a03cc7"), "b": "hello", "c": [ false, null, 15 ] })
The following queries search field b for the string hello using the text operator and sorts the results by field c.
Note
Setting noData: lowest in your sort syntax is the same as the default.
For an ascending sort, MongoDB Search uses the element with the lowest BSON type to represent the multi-typed array. By default, MongoDB Search considers null or missing values as the lowest BSON value. Therefore, MongoDB Search uses null to represent the multi-typed array for the document with _id: 7 and returns this document at the top of the results along with other null and missing values.
To learn more, see Sort by Null and Missing Values and Sort Arrays with Multiple Types.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": 1 } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 } { _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 }, { _id: 2, c: 'foo', score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 1, c: true, score: 0.025981096550822258 } ]
The order of documents with "_id": 4, "_id": 5, "_id": 6, and "_id": 7 is random because MongoDB Search treats null and missing values as equal when sorting.
For a descending sort, MongoDB Search uses the element with the highest BSON type to represent the multi-typed array. MongoDB Search uses false to represent the multi-typed array for the document with _id: 7, as this is the highest BSON type in the array. Since MongoDB Search also ranks true values above false values, MongoDB Search returns this document after the document with _id: 1.
To learn more, see Sort by Null and Missing Values and Sort Arrays with Multiple Types.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": -1 } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 1, c: true, score: 0.025981096550822258 }, { _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 2, c: 'foo', score: 0.025981096550822258 } { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 }, ]
The order of documents with "_id": 4, "_id": 5, and "_id": 6 is random because MongoDB Search treats null and missing values as equal when sorting.
The following queries specify noData: highest to set null values as the highest BSON type during sorting.
For an ascending sort, MongoDB Search uses the element with the lowest BSON type to represent the multi-typed array. The query specifies noData: highest to consider null or missing values as the highest BSON value, so MongoDB Search uses 15 to represent the multi-typed array for the document with _id: 7 since numbers are the next lowest BSON type in the array.
To learn more, see Sort by Null and Missing Values and Sort Arrays with Multiple Types.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": { "order": 1, "noData": "highest" } } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 }, { _id: 2, c: 'foo', score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 1, c: true, score: 0.025981096550822258 }, { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 } ]
The order of documents with "_id": 4, "_id": 5, and "_id": 6 is random because MongoDB Search treats null and missing values as equal when sorting.
For a descending sort, MongoDB Search uses the element with the highest BSON type to represent the multi-typed array. Since the query specifies the noData field as highest to set null or missing values as the highest BSON value, MongoDB Search uses null to represent the multi-typed array for the document with _id: 7 and returns this document at the top of the results along with other null and missing values.
To learn more, see Sort by Null and Missing Values and Sort Arrays with Multiple Types.
db.users.aggregate([ { "$search": { "text": { "path": "b", "query": "hello" }, "sort": { "c": { "order": -1, "noData": "highest" } } } }, { "$project": { "_id": 1, "c": 1, "score": { "$meta": "searchScore" } } } ])
[ { _id: 4, c: null, score: 0.025981096550822258 }, { _id: 5, c: [], score: 0.025981096550822258 }, { _id: 6, score: 0.025981096550822258 }, { _id: 7, c: [ false, null, 15 ], score: 0.025981096550822258 }, { _id: 1, c: true, score: 0.025981096550822258 }, { _id: 0, c: ObjectId('507f1f77bcf86cd799439011'), score: 0.025981096550822258 }, { _id: 3, c: UUID('3be11d4e-62cb-4e95-9a3c-5c9f1e56c732'), score: 0.025981096550822258 }, { _id: 2, c: 'foo', score: 0.025981096550822258 } ]
The order of documents with "_id": 4, "_id": 5, "_id": 6, and "_id": 7 is random because MongoDB Search treats null and missing values as equal when sorting.
Sort by Boolean
The following query searches the sample_airbnb.listingsAndReviews collection for properties in Portugal and sorts the results in descending order by the boolean field is_location_exact.
The query uses the $limit stage to limit the output to 5 documents. It also uses the $project stage to omit all fields except name, property_type, address.country, and address.location.is_location_exact in the results.
1 db.listingsAndReviews.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "address.country", 6 "query": "Portugal" 7 }, 8 "sort": { 9 "address.location.is_location_exact": -1, 10 } 11 } 12 }, 13 { 14 "$limit": 5 15 }, 16 { 17 "$project": { 18 "_id": 0, 19 "name": 1, 20 "property_type": 1, 21 "address.country": 1, 22 "address.location.is_location_exact": 1 23 } 24 } 25 ])
1 [ 2 { 3 name: 'BBC OPORTO 4X2', 4 property_type: 'Apartment', 5 address: { country: 'Portugal', location: { is_location_exact: true } } 6 }, 7 { 8 name: 'Heroísmo IV', 9 property_type: 'Apartment', 10 address: { country: 'Portugal', location: { is_location_exact: true } } 11 }, 12 { 13 name: 'Spacious and well located apartment', 14 property_type: 'Apartment', 15 address: { country: 'Portugal', location: { is_location_exact: true } } 16 }, 17 { 18 name: 'Renovated Classic Design Studio with Sun Room', 19 property_type: 'Apartment', 20 address: { country: 'Portugal', location: { is_location_exact: true } } 21 }, 22 { 23 name: "O'Porto Studio | Historic Center", 24 property_type: 'Loft', 25 address: { country: 'Portugal', location: { is_location_exact: true } } 26 } 27 ]
In the preceding results, the value of is_location_exact is true for the documents because in a descending sort, MongoDB Search ranks true values above false values. If you do an ascending sort by changing the value on line 9 of the preceding query to 1, MongoDB Search ranks the documents with false values higher than true values and returns the following documents:
[ { name: 'Ribeira Charming Duplex', property_type: 'House', address: { country: 'Portugal', location: { is_location_exact: false } } }, { name: 'Be Happy in Porto', property_type: 'Loft', address: { country: 'Portugal', location: { is_location_exact: false } } }, { name: 'Downtown Oporto Inn (room cleaning)', property_type: 'Hostel', address: { country: 'Portugal', location: { is_location_exact: false } } }, { name: 'A Casa Alegre é um apartamento T1.', property_type: 'Apartment', address: { country: 'Portugal', location: { is_location_exact: false } } }, { name: 'FloresRooms 3T', property_type: 'Apartment', address: { country: 'Portugal', location: { is_location_exact: false } } } ]
Compound Search and Sort
The following query uses the $search stage to do the following:
Search for movies that have the term
dancein the title, with a preference for movies that have won 2 or more awards and were released after 01 January, 1990.Sort the results by the number of awards in descending order, then by the movie title in ascending order, and then by the release date in descending order.
The query uses the $limit stage to limit the output to 10 documents. It also uses the $project stage to do the following:
Omit all fields except
title,released, andawards.winsin the results.Add a field named
score.
db.movies.aggregate([ { "$search": { "compound": { "must": [{ "text": { "path": "title", "query": "dance" } }], "should": [{ "range": { "path": "awards.wins", "gte": 2 } }, { "range": { "path": "released", "gte": ISODate("1990-01-01T00:00:00.000Z") } }] }, "sort": { "awards.wins": -1, "title": 1, "released": -1 } } }, { "$limit": 10 }, { "$project": { "_id": 0, "title": 1, "released": 1, "awards.wins": 1, "score": { "$meta": "searchScore" } } } ])
[ { title: 'Shall We Dance?', released: ISODate("1997-07-11T00:00:00.000Z"), awards: { wins: 57 }, score: 4.9811458587646484 }, { title: 'Shall We Dance?', released: ISODate("1997-07-11T00:00:00.000Z"), awards: { wins: 57 }, score: 4.9811458587646484 }, { title: 'War Dance', released: ISODate("2008-11-01T00:00:00.000Z"), awards: { wins: 11 }, score: 5.466421127319336 }, { title: 'Dance with the Devil', released: ISODate("1997-10-31T00:00:00.000Z"), awards: { wins: 6 }, score: 4.615056037902832 }, { title: 'Save the Last Dance', released: ISODate("2001-01-12T00:00:00.000Z"), awards: { wins: 6 }, score: 4.615056037902832 }, { title: 'Dance with a Stranger', released: ISODate("1985-08-09T00:00:00.000Z"), awards: { wins: 4 }, score: 3.615056037902832 }, { title: 'The Baby Dance', released: ISODate("1998-08-23T00:00:00.000Z"), awards: { wins: 4 }, score: 4.981145858764648 }, { title: 'Three-Step Dance', released: ISODate("2004-02-19T00:00:00.000Z"), awards: { wins: 4 }, score: 4.981145858764648 }, { title: "Cats Don't Dance", released: ISODate("1997-03-26T00:00:00.000Z"), awards: { wins: 3 }, score: 4.981145858764648 }, { title: 'Dance Me Outside', released: ISODate("1995-03-10T00:00:00.000Z"), awards: { wins: 3 }, score: 4.981145858764648 } ]
Facet Search and Sort
The following query uses the $search stage to do the following:
Search for movies released between 01 January, 2010 and 01, January, 2015 using the range operator.
Get a count of the number of movies that won
1,5,10, and15awards.Get a count of the number of movies released on
2010-01-01,2011-01-01,2012-01-01,2013-01-01,2014-01-01, and2015-01-01.Sort the results in descending order of released date using the
sortoption.
The query uses the $limit stage to do the following:
Limit the output to
5documents in thedocsoutput field.Limit the output to
1document in themetaoutput field.
It uses the $project stage to omit all fields except the awards.wins, released, and title fields.
It also uses the $replaceWith stage to include the metadata results stored in the $$SEARCH_META variable in the meta output field and the $set stage to add the meta field to the results.
db.movies.aggregate([ { "$search": { "facet": { "operator": { "range": { "path": "released", "gt": ISODate("2010-01-01T00:00:00.000Z"), "lt": ISODate("2015-01-01T00:00:00.000Z") } }, "facets": { "awardsFacet": { "type": "number", "path": "awards.wins", "boundaries" : [1,5,10,15] }, "releasedFacet" : { "type" : "date", "path" : "released", "boundaries" : [ISODate("2010-01-01T00:00:00.000Z"), ISODate("2011-01-01T00:00:00.000Z"), ISODate("2012-01-01T00:00:00.000Z"), ISODate("2013-01-01T00:00:00.000Z"), ISODate("2014-01-01T00:00:00.000Z"), ISODate("2015-01-01T00:00:00.000Z")] } } }, "sort": { "released": -1 } } }, { "$facet": { "docs": [ { "$limit": 5 }, { "$project": { "_id": 0, "title": 1, "released": 1, "awards.wins": 1 } } ], "meta": [ {"$replaceWith": "$$SEARCH_META"}, {"$limit": 1} ] } }, { "$set": { "meta": { "$arrayElemAt": ["$meta", 0] } } } ])
[ { docs: [ { title: 'Cold in July', released: ISODate("2014-12-31T00:00:00.000Z"), awards: { wins: 1 } }, { title: 'The Gambler', released: ISODate("2014-12-31T00:00:00.000Z"), awards: { wins: 7 } }, { title: 'Force Majeure', released: ISODate("2014-12-30T00:00:00.000Z"), awards: { wins: 31 } }, { title: 'LFO', released: ISODate("2014-12-27T00:00:00.000Z"), awards: { wins: 3 } }, { title: 'Peace After Marriage', released: ISODate('2014-12-26T00:00:00.000Z'), awards: { wins: 5 } } ], meta: { count: { lowerBound: Long("4821") }, facet: { releasedFacet: { buckets: [ { _id: ISODate("2010-01-01T00:00:00.000Z"), count: Long("857") }, { _id: ISODate("2011-01-01T00:00:00.000Z"), count: Long("909") }, { _id: ISODate("2012-01-01T00:00:00.000Z"), count: Long("903") }, { _id: ISODate("2013-01-01T00:00:00.000Z"), count: Long("1063") }, { _id: ISODate("2014-01-01T00:00:00.000Z"), count: Long("1089") } ] }, awardsFacet: { buckets: [ { _id: 1, count: Long("2330") }, { _id: 5, count: Long("604") }, { _id: 10, count: Long("233") } ] } } } } } ]
Sort by Score
The following examples demonstrate how to sort the results by the score of the documents in the results. The examples demonstrate how to perform the following actions:
Retrieve the lowest scoring documents first by sorting the results in ascending order.
Sort the results by score in descending order and for results with identical scores, sort arbitrarily.
Sort the results by score and for results with identical scores, sort using a unique field.
The following query uses the $search stage to perform the following actions:
Search for movies that have the term
storyin the title.Sort the results by score in ascending order.
The query uses the $limit stage to limit the output to 5 documents. It also uses the $project stage to perform the following actions:
Omit all fields except
titlein the results.Add a field named
score.
db.movies.aggregate([ { "$search": { "text": { "path": "title", "query": "story" }, "sort": {score: {$meta: "searchScore", order: 1}} } }, { "$limit": 5 }, { "$project": { "_id": 0, "title": 1, "score": {$meta: "searchScore"} } } ])
[ { title: 'Do You Believe in Miracles? The Story of the 1980 U.S. Hockey Team', score: 0.8674521446228027 }, { title: 'Once in a Lifetime: The Extraordinary Story of the New York Cosmos', score: 0.9212141036987305 }, { title: 'The Source: The Story of the Beats and the Beat Generation', score: 0.9820802211761475 }, { title: 'If These Knishes Could Talk: The Story of the NY Accent', score: 0.9820802211761475 }, { title: 'Dream Deceivers: The Story Behind James Vance vs. Judas Priest', score: 1.051558256149292 } ]
The following query uses the $search stage to perform the following actions:
Search for movies that have the term
summerin the title.Sort the results by score in descending order and for results with identical scores, sort arbitrarily.
The query uses the $limit stage to limit the output to 5 documents. It also uses the $project stage to perform the following actions:
Omit all fields except
_idandtitlein the results.Add a field named
score.
db.movies.aggregate([ { "$search": { "text": { "path": "title", "query": "summer" }, "sort": {score: {$meta: "searchScore"}} } }, { "$limit": 5 }, { "$project": { "_id": 1, "title": 1, "score": {$meta: "searchScore"} } } ])
[ { _id: ObjectId("573a1398f29313caabcea21e"), title: 'Summer', score: 3.5844719409942627 }, { _id: ObjectId("573a13a6f29313caabd18eca"), title: 'Summer Things', score: 3.000213623046875 }, { _id: ObjectId("573a13b8f29313caabd4c1d0"), title: 'Summer Palace', score: 3.000213623046875 }, { _id: ObjectId("573a1394f29313caabcde8e8"), title: 'Summer Stock', score: 3.000213623046875 }, { _id: ObjectId("573a13acf29313caabd284fa"), title: 'Wolf Summer', score: 3.000213623046875 } ]
The following query uses the $search stage to perform the following actions:
Search for movies that have the term
princein the title.Sort the results first by score and then by the value of the
releasedfield in ascending order for results with identical scores.
The query uses the $limit stage to limit the output to 5 documents. It also uses the $project stage to perform the following actions:
Omit all fields except
titleandreleasedin the results.Add a field named
score.
db.movies.aggregate([ { "$search": { "text": { "path": "title", "query": "prince" }, "sort": {score: {$meta: "searchScore"}, "released": 1} } }, { "$limit": 5 }, { "$project": { "_id": 0, "title": 1, "released": 1, "score": {$meta: "searchScore"} } } ])
[ { title: 'Prince', released: ISODate("2015-08-14T00:00:00.000Z"), score: 4.168826103210449 }, { title: 'Prince Avalanche', released: ISODate("2013-09-19T00:00:00.000Z"), score: 3.4893198013305664 }, { title: 'The Prince', released: ISODate("2014-08-22T00:00:00.000Z"), score: 3.4893198013305664 }, { title: 'Prince of Foxes', released: ISODate("1949-12-23T00:00:00.000Z"), score: 3.0002830028533936 }, { title: 'The Oil Prince', released: ISODate("1966-01-01T00:00:00.000Z"), score: 3.0002830028533936 } ]