embeddedDocument
On this page
Note
The Atlas Search embeddedDocuments
type, embeddedDocument operator, and embedded
scoring option are in preview. When an Atlas Search index on a replica set or
single MongoDB shard reaches 2,100,000,000 index objects,
Atlas Search transitions the index to a stale, queryable state. If you would
like Atlas Search to support more than 2,100,000,000 index objects in the
future, vote for this request in the MongoDB
Feedback Engine.
Definition
embeddedDocument
The
embeddedDocument
operator is similar to $elemMatch operator. It constrains multiple query predicates to be satisfied from a single element of an array of embedded documents.embeddedDocument
can be used only for queries over fields of the embeddedDocuments type.
Syntax
embeddedDocument
has the following syntax:
{ "embeddedDocument": { "path": "<path-to-field>", "operator": { <operator-specification> }, "score": { <score-options> } } }
Options
embeddedDocument
uses the following options to construct a query:
Field | Type | Description | Necessity |
---|---|---|---|
| object | Operator to use to query each document in the array of documents
that you specify in the | Required |
| string | Indexed embeddedDocuments type field to
search. The specified field must be a parent for all operators
and fields specified using the | Required |
| object | Score to assign to matching search results. You can use the
| Optional |
Behavior
When you query embedded documents in arrays using the
embeddedDocument
operator, Atlas Search evaluates and scores the operator
query predicates at different stages of query execution. Atlas Search:
Evaluates each embedded document in the array independently.
Combines the scores of matching results as configured using the
embedded
option, or scores by summing the scores of matching results if you don't specify anembedded
score option.Joins the matching results with the parent document if other query predicates are specified through the compound operator.
Note
For string faceting, Atlas Search counts string facets once for each document in the result set. For an example of this behavior, see Examples.
Scoring Behavior
By default, embeddedDocument
operator uses the default aggregation
strategy, sum
, for combining scores of embedded document matches.
The embeddedDocument
operator score
option allows you to
override the default and configure the score of matching results using
the embedded
option.
Sorting Behavior
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.
Atlas Search sorts on parent documents only. It doesn't sort the child fields within an array of documents. For an example, see Sort Example.
Highlighting
You can highlight on fields if the fields are
indexed under a parent field of document type for query predicates specified inside
the embeddedDocument
operator. For an example, see tutorial.
Limitations
You can't highlight on queries inside the
embeddedDocument
operator.
Examples
The following examples use the sample_supplies.sales
collection
in the sample dataset.
Index Definition
These sample queries use the following index definition on the collection:
{ "mappings": { "dynamic": true, "fields": { "items": [ { "dynamic": true, "type": "embeddedDocuments" }, { "dynamic": true, "fields": { "tags": { "type": "token" } }, "type": "document" } ], "purchaseMethod": { "type": "stringFacet" } } } }
Basic Query
The following query searches the collection for items tagged school
with a preference for items named backpack
. Atlas Search scores the results
in descending order based on the average (arithmetic mean) score of all
matching embedded documents. The query includes a $limit
stage to limit the output to 5
documents and a $project
stage to:
Exclude all fields except
items.name
anditems.tags
fieldsAdd a field named
score
1 db.sales.aggregate({ 2 "$search": { 3 "embeddedDocument": { 4 "path": "items", 5 "operator": { 6 "compound": { 7 "must": [{ 8 "text": { 9 "path": "items.tags", 10 "query": "school" 11 } 12 }], 13 "should": [{ 14 "text": { 15 "path": "items.name", 16 "query": "backpack" 17 } 18 }] 19 } 20 }, 21 "score": { 22 "embedded": { 23 "aggregate": "mean" 24 } 25 } 26 } 27 } 28 }, 29 { 30 $limit: 5 31 }, 32 { 33 $project: { 34 "_id": 0, 35 "items.name": 1, 36 "items.tags": 1, 37 "score": { $meta: "searchScore" } 38 } 39 })
[ { items: [ { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] } ], score: 1.2907354831695557 }, { items: [ { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] }, { name: 'printer paper', tags: [ 'office', 'stationary' ] }, { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] } ], score: 1.2907354831695557 }, { items: [ { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] } ], score: 1.2907354831695557 }, { items: [ { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] } ], score: 1.2907354831695557 }, { items: [ { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] } ], score: 1.2907354831695557 } ]
Facet Query
The following query searches for items tagged school
with a
preference for items named backpack
. It requests facet information
on the purchaseMethod
field.
1 db.sales.aggregate({ 2 "$searchMeta": { 3 "facet": { 4 "operator": { 5 "embeddedDocument": { 6 "path": "items", 7 "operator": { 8 "compound": { 9 "must": [ 10 { 11 "text": { 12 "path": "items.tags", 13 "query": "school" 14 } 15 } 16 ], 17 "should": [ 18 { 19 "text": { 20 "path": "items.name", 21 "query": "backpack" 22 } 23 } 24 ] 25 } 26 } 27 } 28 }, 29 "facets": { 30 "purchaseMethodFacet": { 31 "type": "string", 32 "path": "purchaseMethod" 33 } 34 } 35 } 36 } 37 })
[ { count: { lowerBound: Long("2309") }, facet: { purchaseMethodFacet: { buckets: [ { _id: 'In store', count: Long("2751") }, { _id: 'Online', count: Long("1535") }, { _id: 'Phone', count: Long("578") } ] } } } ]
Query and Sort
The following query searches for items named laptop
and it sorts the
results by the items.tags
field. The query includes a
$limit
stage to limit the output to 5
documents and a
$project
stage to:
Exclude all fields except
items.name
anditems.tags
Add a field named
score
1 db.sales.aggregate({ 2 "$search": { 3 "embeddedDocument": { 4 "path": "items", 5 "operator": { 6 "text": { 7 "path": "items.name", 8 "query": "laptop" 9 } 10 } 11 }, 12 "sort": { 13 "items.tags": 1 14 } 15 } 16 }, 17 { 18 "$limit": 5 19 }, 20 { 21 "$project": { 22 "_id": 0, 23 "items.name": 1, 24 "items.tags": 1, 25 "score": { "$meta": "searchScore" } 26 } 27 })
1 [ 2 { 3 items: [ 4 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] }, 5 { name: 'binder', tags: [ 'school', 'general', 'organization' ] }, 6 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 7 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] }, 8 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 9 { name: 'printer paper', tags: [ 'office', 'stationary' ] }, 10 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] }, 11 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] }, 12 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] } 13 ], 14 score: 1.168686032295227 15 }, 16 { 17 items: [ 18 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 19 { name: 'binder', tags: [ 'school', 'general', 'organization' ] }, 20 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 21 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] }, 22 { name: 'printer paper', tags: [ 'office', 'stationary' ] }, 23 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] }, 24 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 25 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] }, 26 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] } 27 ], 28 score: 1.168686032295227 29 }, 30 { 31 items: [ 32 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] }, 33 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 34 { name: 'binder', tags: [ 'school', 'general', 'organization' ] }, 35 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] }, 36 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 37 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] }, 38 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] } 39 ], 40 score: 1.168686032295227 41 }, 42 { 43 items: [ 44 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] }, 45 { name: 'binder', tags: [ 'school', 'general', 'organization' ] }, 46 { name: 'binder', tags: [ 'school', 'general', 'organization' ] }, 47 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] }, 48 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 49 { name: 'printer paper', tags: [ 'office', 'stationary' ] }, 50 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] }, 51 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 52 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] }, 53 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] } 54 ], 55 score: 1.168686032295227 56 }, 57 { 58 items: [ 59 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] }, 60 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 61 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }, 62 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] }, 63 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] }, 64 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] }, 65 { name: 'binder', tags: [ 'school', 'general', 'organization' ] }, 66 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] }, 67 { name: 'printer paper', tags: [ 'office', 'stationary' ] }, 68 { name: 'binder', tags: [ 'school', 'general', 'organization' ] } 69 ], 70 score: 1.168686032295227 71 } 72 ]
Query for Matching Embedded Documents Only
The following query returns only the nested documents that match the
query. The query uses Atlas Search compound operator clauses in the
$search
stage to find matching documents and then the
aggregation operators in
the $project
stage to return only matching embedded documents.
Specifically, the query specifies the following pipeline stages:
Specifies the following criteria in the compound
operator
| |
Limits the output to | |
1 db.sales.aggregate( 2 { 3 "$search": { 4 "embeddedDocument": { 5 "path": "items", 6 "operator": { 7 "compound": { 8 "must": [ 9 { 10 "range": { 11 "path": "items.quantity", 12 "gt": 2 13 } 14 }, 15 { 16 "exists": { 17 "path": "items.price" 18 } 19 }, 20 { 21 "text": { 22 "path": "items.tags", 23 "query": "school" 24 } 25 } 26 ] 27 } 28 } 29 } 30 } 31 }, 32 { 33 "$limit": 2 34 }, 35 { 36 "$project": { 37 "_id": 0, 38 "storeLocation": 1, 39 "items": { 40 "$filter": { 41 "input": "$items", 42 "cond": { 43 "$and": [ 44 { 45 "$ifNull": [ 46 "$$this.price", "false" 47 ] 48 }, 49 { 50 "$gt": [ 51 "$$this.quantity", 2 52 ] 53 }, 54 { 55 "$in": [ 56 "office", "$$this.tags" 57 ] 58 } 59 ] 60 } 61 } 62 } 63 } 64 } 65 )
1 [ 2 { 3 storeLocation: 'Austin', 4 items: [ 5 { 6 name: 'laptop', 7 tags: [ 'electronics', 'school', 'office' ], 8 price: Decimal128('753.04'), 9 quantity: 3 10 }, 11 { 12 name: 'pens', 13 tags: [ 'writing', 'office', 'school', 'stationary' ], 14 price: Decimal128('19.09'), 15 quantity: 4 16 }, 17 { 18 name: 'notepad', 19 tags: [ 'office', 'writing', 'school' ], 20 price: Decimal128('30.23'), 21 quantity: 5 22 }, 23 { 24 name: 'pens', 25 tags: [ 'writing', 'office', 'school', 'stationary' ], 26 price: Decimal128('20.05'), 27 quantity: 4 28 }, 29 { 30 name: 'notepad', 31 tags: [ 'office', 'writing', 'school' ], 32 price: Decimal128('22.08'), 33 quantity: 3 34 }, 35 { 36 name: 'notepad', 37 tags: [ 'office', 'writing', 'school' ], 38 price: Decimal128('21.67'), 39 quantity: 4 40 } 41 ] 42 }, 43 { 44 storeLocation: 'Austin', 45 items: [ 46 { 47 name: 'notepad', 48 tags: [ 'office', 'writing', 'school' ], 49 price: Decimal128('24.16'), 50 quantity: 5 51 }, 52 { 53 name: 'notepad', 54 tags: [ 'office', 'writing', 'school' ], 55 price: Decimal128('28.04'), 56 quantity: 5 57 }, 58 { 59 name: 'notepad', 60 tags: [ 'office', 'writing', 'school' ], 61 price: Decimal128('21.42'), 62 quantity: 5 63 }, 64 { 65 name: 'laptop', 66 tags: [ 'electronics', 'school', 'office' ], 67 price: Decimal128('1540.63'), 68 quantity: 3 69 }, 70 { 71 name: 'pens', 72 tags: [ 'writing', 'office', 'school', 'stationary' ], 73 price: Decimal128('29.43'), 74 quantity: 5 75 }, 76 { 77 name: 'pens', 78 tags: [ 'writing', 'office', 'school', 'stationary' ], 79 price: Decimal128('28.48'), 80 quantity: 5 81 } 82 ] 83 } 84 ]
Tip
To return only matching embedded documents in the results, include an
equivalent $filter
to match the $search
criteria on the embedded document field. To return only matching
embedded documents in the $search
stage results, upvote
this request
in the MongoDB Feedback Engine.