Definition
Syntax
compound has the following syntax:
1 { 2 $search: { 3 "index": <index name>, // optional, defaults to "default" 4 "compound": { 5 <must | mustNot | should | filter>: [ { <clauses> } ], 6 "score": <options> 7 } 8 } 9 }
Each must, mustNot, should, and filter clause contains
an array of subclauses. Use array syntax even if the array contains
only one subclause. See the examples on
this page.
Options
compound uses the following terms to construct a query:
Clauses that must match to for a document to be included in the results. The returned score is the sum of the scores of all the subqueries in the clause. Maps to the | ||||||||||||||
Clauses that must not match for a document to be included in
the results. Maps to the | ||||||||||||||
Clauses that you prefer to match in documents that are included
in the results. Documents that contain a match for a If you use more than one See an example. Maps to the If you use only the | ||||||||||||||
Clauses that must all match for a document to be
included in the results. For example, you can replace the You can use the See another filter example. | ||||||||||||||
| Modify the score of the entire |
Usage
You can use any of the clauses with any top-level operator, such as autocomplete, text, or span, to specify query criteria.
To optimize performance, place non-scoring operators such as
equals, range, and in in the
filter clause to avoid unnecessary scoring operations. If you
want to run multiple operations that must be evaluated as an OR
condition, nest a should clause within the top-level
filter.
Example
[ { $search: { index: "default", compound: { filter: [ { compound: { should: [ { equals: { path: "accommodates", value: 2 } }, { range: { path: "pricePerNight", lte: 200 } } ] } } ] } } } ]
Scoring Behavior
MongoDB Search scores documents in the result set by summing the score that the
document received for each individual clause that generated a match on
the document. Only must and should clauses participate in
scoring. The result set is ordered by score, highest to lowest.
The following table shows the compound clauses that contribute and
don't contribute to the score.
Clause | Contributes to Score |
|---|---|
| |
| |
| |
|
You can boost or replace the score of the entire compound query using
the score option. For an example of replacing the entire compound
score, see Compound Score Example below.
You can use score to also boost or alter the score
for each subquery in each clause. For some examples of altered scores in
compound operator clauses, see Modify the Score.
Examples
You can try the following examples in the MongoDB Search Playground or your cluster.
Sample Collection
The examples on this page use a collection called fruit, which
contains the following documents:
1 { 2 "_id" : 1, 3 "type" : "apple", 4 "description" : "Apples come in several varieties, including Fuji, Granny Smith, and Honeycrisp.", 5 "category" : "nonorganic", 6 "in_stock" : false 7 }, 8 { 9 "_id" : 2, 10 "type" : "banana", 11 "description" : "Bananas are usually sold in bunches of five or six.", 12 "category" : "nonorganic", 13 "in_stock" : true 14 }, 15 { 16 "_id" : 3, 17 "type" : "pear", 18 "description" : "Bosc and Bartlett are the most common varieties of pears.", 19 "category" : "organic", 20 "in_stock" : true 21 }
Sample Index
The fruit collection has a default index with dynamic mappings that automatically indexes all the fields in
the collection and uses the default standard analyzer. The standard analyzer lower-cases
all words and disregards common stop words ("the", "a", "and", etc).
Sample Queries
The following queries demonstrate the $search compound
operator in MongoDB Search queries.
must and mustNot Example
The following example uses a combination of must and mustNot
clauses to contruct a query. The must clause uses the
text operator to search for the term varieties
in the description field. For a document to match, it must fulfill
the must clause. The mustNot clause performs a search operation
for the term apples in the description field. For a document to
match, it must not fulfill the mustNot clause.
1 db.fruit.aggregate([ 2 { 3 "$search": { 4 "compound": { 5 "must": [{ 6 "text": { 7 "query": "varieties", 8 "path": "description" 9 } 10 }], 11 "mustNot": [{ 12 "text": { 13 "query": "apples", 14 "path": "description" 15 } 16 }] 17 } 18 } 19 } 20 ])
The above query returns the document with _id: 3 because its
description field contains the word varieties and does not
contain apples.
➤ Try this in the MongoDB Search Playground.
must and should Example
The following queries use must to specify search conditions
that must be met and should to specify preference for documents
that contain the word Fuji.
For this query, the $project pipeline stage excludes all
document fields except _id and adds a score field, which
displays the document's relevance score.
1 db.fruit.aggregate([ 2 { 3 "$search": { 4 "compound": { 5 "must": [{ 6 "text": { 7 "query": "varieties", 8 "path": "description" 9 } 10 }], 11 "should": [{ 12 "text": { 13 "query": "Fuji", 14 "path": "description" 15 } 16 }] 17 } 18 } 19 }, 20 { 21 "$project": { 22 "score": { "$meta": "searchScore" } 23 } 24 } 25 ])
{ "_id" : 1, "score" : 0.6425117254257202 } { "_id" : 3, "score" : 0.21649497747421265 }
The document with _id: 1 has a higher score because its
description field contains the word Fuji, satisfying the
should clause.
➤ Try this in the MongoDB Search Playground.
The following query also specifies a constant
score of 3 for all the documents in the results. For this
query, the $project pipeline stage excludes all document
fields except _id and adds a score field.
1 db.fruit.aggregate([ 2 { 3 "$search": { 4 "compound": { 5 "must": [{ 6 "text": { 7 "query": "varieties", 8 "path": "description" 9 } 10 }], 11 "should": [{ 12 "text": { 13 "query": "Fuji", 14 "path": "description" 15 } 16 }], 17 "score": { "constant": { "value": 3 } } 18 } 19 } 20 }, 21 { 22 "$project": { 23 "score": { "$meta": "searchScore" } 24 } 25 } 26 ])
[ { _id: 1, score: 3 }, { _id: 3, score: 3 } ]
Both the documents receive the same score because the
constant option in the query replaces the score of each
document in the result with the number 3.
➤ Try this in the MongoDB Search Playground.
minimumShouldMatch Example
In a query with multiple should clauses, you can use the
miniumumShouldMatch option to specify a minimum number of clauses
which must match to return a result.
The following query has one must clause and two should clauses,
with a minimumShouldMatch value of 1. A document must include
the term varieties in the description field and must include
either Fuji or Golden Delicious in the description field to be
included in the result set.
1 db.fruit.aggregate([ 2 { 3 $search: { 4 "compound": { 5 "must": [{ 6 "text": { 7 "query": "varieties", 8 "path": "description" 9 } 10 }], 11 "should": [{ 12 "text": { 13 "query": "Fuji", 14 "path": "description" 15 } 16 }, 17 { 18 "text": { 19 "query": "Golden Delicious", 20 "path": "description" 21 } 22 }], 23 "minimumShouldMatch": 1 24 } 25 } 26 } 27 ])
1 { 2 "_id" : 1, 3 "type" : "apple", 4 "description" : "Apples come in several varieties, including Fuji, Granny Smith, and Honeycrisp.", 5 "category" : "nonorganic", 6 "in_stock" : false 7 }
The document with _id: 1 matches the must clause and the first
of the two should clauses.
➤ Try this in the MongoDB Search Playground.
filter Examples
filter behaves the same as must, except that the filter
clause is not considered in a returned document's score, and therefore
does not affect the order of the returned documents.
The following query uses the following clauses:
mustandfilterto specify search conditions which must be met.shouldto specify preference for documents containing the wordbanana. Theshouldclause doesn't include theminimumShouldMatchoption. When you omitminimumShouldMatch, it defaults to0.
1 db.fruit.aggregate([ 2 { 3 "$search": { 4 "compound": { 5 "must": [{ 6 "text": { 7 "query": "varieties", 8 "path": "description" 9 } 10 }], 11 "should": [{ 12 "text": { 13 "query": "banana", 14 "path": "description" 15 } 16 }], 17 "filter": [{ 18 "text": { 19 "query": "granny", 20 "path": "description" 21 } 22 }] 23 } 24 } 25 } 26 ])
1 { 2 "_id" : 1, 3 "type" : "apple", 4 "description" : "Apples come in several varieties, including Fuji, Granny Smith, and Honeycrisp.", 5 "category" : "nonorganic", 6 "in_stock" : false 7 }
The returned document fulfills all the requirements for inclusion:
Both the
mustclause and thefilterclause match.The
minimumShouldMatchvalue is not specified, so it defaults to0. As a result, theshouldclause fails and still returns a document.
➤ Try this in the MongoDB Search Playground.
You can replace the $match with $in in your
queries against data on your cluster with the
filter clause. The following query demonstrates how to use
filter in the $search stage to specify the search
terms that must match. The query also uses should to specify
preference for documents containing the term varieties. The
query includes the $project pipeline stage to do the
following:
Exclude all fields except
_idanddescription.Add a
scorefield, which displays the document's relevance score.
1 db.fruit.aggregate([ 2 { 3 "$search": { 4 "compound": { 5 "filter": [{ 6 "text": { 7 "query": ["apples", "bananas"], 8 "path": "description" 9 } 10 }], 11 "should": [{ 12 "text": { 13 "query": "varieties", 14 "path": "description" 15 } 16 }] 17 } 18 } 19 }, 20 { 21 "$project": { 22 "description": 1, 23 "score": { "$meta": "searchScore" } 24 } 25 } 26 ])
1 [ 2 { 3 _id: 1, 4 description: 'Apples come in several varieties, including Fuji, Granny Smith, and Honeycrisp. The most popular varieties are McIntosh, Gala, and Granny Smith.', 5 score: 0.36074575781822205 6 }, 7 { 8 _id: 2, 9 description: 'Bananas are usually sold in bunches of five or six.', 10 score: 0 11 } 12 ]
The documents in the result fulfill all the requirements for inclusion:
Both documents contain the term
applesorbananasthat was specified in thefilterclause of the query.Document with
_id: 1scores higher than document with_id: 2because it contains the termvarietiesspecified in theshouldclause of the query.
➤ Try this in the MongoDB Search Playground.
Nested Example
The following example uses nested compound clauses to construct a
query. For this example, the fruit collection has an index on the
type, category, and in_stock fields, whose text fields use the
default analyzer. The query requires
documents to only satisfy one of the following should clauses:
Contain the word
applein thetypefield.Contain the term
organicin thecategoryfield and have the valuetruein thein_stockfield.
1 db.fruit.aggregate([ 2 { 3 $search: { 4 "compound": { 5 "should": [ 6 { 7 "text": { 8 "query": "apple", 9 "path": "type" 10 } 11 }, 12 { 13 "compound": { 14 "must": [ 15 { 16 "text": { 17 "query": "organic", 18 "path": "category" 19 } 20 }, 21 { 22 "equals": { 23 "value": true, 24 "path": "in_stock" 25 } 26 } 27 ] 28 } 29 } 30 ], 31 "minimumShouldMatch": 1 32 } 33 } 34 } 35 ])
1 { 2 "_id" : 3, 3 "type" : "pear", 4 "description" : "Bosc and Bartlett are the most common varieties of pears.", 5 "category" : "organic", 6 "in_stock" : true 7 } 8 { 9 "_id" : 1, 10 "type" : "apple", 11 "description" : "Apples come in several varieties, including Fuji, Granny Smith, and Honeycrisp.", 12 "category" : "nonorganic", 13 "in_stock" : false 14 }
The documents in the results fulfill all the requirements for inclusion:
The document with
_id: 3matches themustclause nested within the secondshouldclause.The document with
_id: 1matches the firstshouldclause.
➤ Try this in the MongoDB Search Playground.
Metadata Examples
The following queries retrieve metadata to return the number of
categories in the fruit collection using either the $searchMeta pipeline stage
or the $$SEARCHMETA variable of the $search stage.