embeddedDocument Operator

For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

embeddedDocument Operator

Definition

The embeddedDocument operator is similar to [$elemMatch](https://www.mongodb.com/docs/manual/reference/operator/query/elemMatch.md#mongodb-query-op.-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](https://www.mongodb.com/docs/search/indexes/field-types/embedded-documents-type.md#std-label-bson-data-types-embedded-documents 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
operator object Operator to use to query each document in the array of documents that you specify in the path. The [moreLikeThis](https://www.mongodb.com/docs/search/query/operators-collectors/morelikethis.md#std-label-more-like-this-ref operator is not supported. Required
path string Indexed [embeddedDocuments](https://www.mongodb.com/docs/search/indexes/field-types/embedded-documents-type.md#std-label-bson-data-types-embedded-documents type field to search. The specified field must be a parent for all operators and fields specified using the operator option. Required
score object Score to assign to matching search results. You can use the [embedded](https://www.mongodb.com/docs/search/query/score/modify-score.md#std-label-scoring-embedded scoring option to configure scoring options. To learn more, see [Scoring Behavior.](https://www.mongodb.com/docs/search/query/operators-collectors/embedded-document.md#std-label-embedded-document-query-score Optional

embeddedDocument Operator Limitations

You can't use [highlight](https://www.mongodb.com/docs/search/query/highlighting.md#std-label-highlight-ref in queries inside the embeddedDocument operator.

Note:

MongoDB Search stops replicating changes for indexes larger than 2,100,000,000 index objects per partition, on a replica set or single shard, where each indexed embedded parent document counts as a single object. Surpassing this limit may result in stale query results.

Using the embeddedDocuments field type can result in indexing objects over this index size limit, because each indexed embedded document is counted as a single object. If you create a MongoDB Search index that has or will soon have more than 2.1 billion index objects, use the [numPartitions](https://www.mongodb.com/docs/search/indexes/index-partition.md#std-label-fts-index-partition index option to partition your index (supported only on Search Nodes deployments) or [shard your cluster.](https://www.mongodb.com/docs/atlas/cluster-additional-settings.md#std-label-create-cluster-sharding

Behavior

When you query embedded documents in arrays using the embeddedDocument operator, MongoDB Search evaluates and scores the operator query predicates at different stages of query execution. MongoDB Search:

  1. Evaluates each embedded document in the array independently.

  2. Combines the scores of matching results as configured using the embedded.

  3. Joins the matching results with the parent document if other query predicates are specified through the [compound.](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref

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](https://www.mongodb.com/docs/search/query/score/modify-score.md#std-label-scoring-embedded option.

See also:

[Score the Documents in the Results](https://www.mongodb.com/docs/search/query/score/overview.md#std-label-scoring-ref

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](https://www.mongodb.com/docs/search/indexes/field-types/document-type.md#std-label-bson-data-types-document type.

  • Index the child field with string values within the embedded document as the [token](https://www.mongodb.com/docs/search/indexes/field-types/token-type.md#std-label-bson-data-types-token type. For child fields with number and date values, enable [dynamic mapping](https://www.mongodb.com/docs/search/indexes/define-field-mappings.md#std-label-static-dynamic-mappings 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.](https://www.mongodb.com/docs/search/query/operators-collectors/embedded-document.md#std-label-embedded-document-query-examples

Faceting Behavior

To facet on only the child documents in an embeddedDocuments array that match your query, add a matching embeddedDocument block to the facet definition, in addition to using embeddedDocument in the query's operator. If you omit the embeddedDocument block on the facet definition, MongoDB Search facets on all child documents in the array, not just the ones that match your query. To learn more, see [Facet on Matching Children of an Embedded Documents Array.](https://www.mongodb.com/docs/search/query/operators-collectors/facet.md#std-label-fts-facet-embedded-scoped

Highlighting

You can [highlight](https://www.mongodb.com/docs/search/query/highlighting.md#std-label-highlight-ref on fields if the fields are indexed under a parent field of [document](https://www.mongodb.com/docs/search/indexes/field-types/document-type.md#std-label-bson-data-types-document type for query predicates specified inside the embeddedDocument operator. For an example, see [tutorial.](https://www.mongodb.com/docs/search/tutorial/embedded-documents-tutorial.md#std-label-embedded-documents-tutorial

To learn about the embeddedDocument operator limitations, see [embeddedDocument Operator Limitations.](https://www.mongodb.com/docs/search/query/operators-collectors/embedded-document.md#std-label-embedded-document-query-limitations

Examples

The following examples use the sample_supplies.sales collection in the [sample dataset.](https://www.mongodb.com/docs/manual/sample-data.md#std-label-available-sample-datasets

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": "token"
      }
    }
  }
}

Basic Query

The following query searches the collection for items tagged school with a preference for items named backpack. MongoDB Search scores the results in descending order based on the average (arithmetic mean) score of all matching embedded documents. The query includes a [$limit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit stage to limit the output to 5 documents and a [$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to:

  • Exclude all fields except items.name and items.tags fields

  • Add a field named score

db.sales.aggregate({
  "$search": {
    "embeddedDocument": {
      "path": "items",
      "operator": {
        "compound": {
          "must": [{
            "text": {
              "path": "items.tags",
              "query": "school"
            }
          }],
          "should": [{
            "text": {
              "path": "items.name",
              "query": "backpack"
            }
          }]
        }
      },
      "score": {
        "embedded": {
          "aggregate": "mean"
        }
      }
    }
  }
},
{
  $limit: 5
},
{
  $project: {
    "_id": 0,
    "items.name": 1,
    "items.tags": 1,
    "score": { $meta: "searchScore" }
  }
})

Output:

[
  {
    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.

db.sales.aggregate({
  "$searchMeta": {
    "facet": {
      "operator": {
        "embeddedDocument": {
          "path": "items",
          "operator": {
            "compound": {
              "must": [
                {
                  "text": {
                    "path": "items.tags",
                    "query": "school"
                  }
                }
              ],
              "should": [
                {
                  "text": {
                    "path": "items.name",
                    "query": "backpack"
                  }
                }
              ]
            }
          }
        }
      },
      "facets": {
        "purchaseMethodFacet": {
          "type": "string",
          "path": "purchaseMethod"
        }
      }
    }
  }
})

Output:

[
  {
    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](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit stage to limit the output to 5 documents and a [$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to:

  • Exclude all fields except items.name and items.tags

  • Add a field named score

db.sales.aggregate({
  "$search": {
    "embeddedDocument": {
      "path": "items",
      "operator": {
        "text": {
          "path": "items.name",
          "query": "laptop"
        }
      }
    },
    "sort": {
      "items.tags": 1
    }
  }
},
{
  "$limit": 5
},
{
  "$project": {
    "_id": 0,
    "items.name": 1,
    "items.tags": 1,
    "score": { "$meta": "searchScore" }
  }
})

Output:

[
  {
    items: [
      { name: 'envelopes',  tags: [ 'stationary', 'office', 'general' ] },
      { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'printer paper', tags: [ 'office', 'stationary' ] },
      { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
      { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
      { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] }
    ],
    score: 1.168686032295227
  },
  {
    items: [
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
      { name: 'printer paper', tags: [ 'office', 'stationary' ] },
      { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
      { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] }
    ],
    score: 1.168686032295227
  },
  {
    items: [
      { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
      { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] },
      { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] }
    ],
    score: 1.168686032295227
  },
  {
    items: [
      { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] },
      { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
      { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
      { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'printer paper', tags: [ 'office', 'stationary' ] },
      { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }
    ],
    score: 1.168686032295227
  },
  {
    items: [
      { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
      { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
      { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] },
      { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
      { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
      { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] },
      { name: 'printer paper', tags: [ 'office', 'stationary' ] },
      { name: 'binder', tags: [ 'school', 'general', 'organization' ] }
    ],
    score: 1.168686032295227
  }
]

Query for Matching Embedded Documents Only

The following query returns only the nested documents that match the query. The query uses MongoDB Search [compound operator](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref clauses in the [$search](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search stage to find matching documents and then the [aggregation operators](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions in the [$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to return only matching embedded documents. Specifically, the query specifies the following pipeline stages:

[$search](https://www.mongodb.com/docs/search/query/aggregation-stages/search.md#mongodb-pipeline-pipe.-search Specifies the following criteria in the [compound operator](https://www.mongodb.com/docs/search/query/operators-collectors/compound.md#std-label-compound-ref must clause: Check if items.price field exists in the collection.; Search for the items tagged as school in the items.tags field.; Match only if value is more than 2 for the items.quantity field.
[$limit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit Limits the output to 5 documents.
[$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project Perform the following actions: Exclude the _id field and only include the items and storeLocation fields.; Use [$filter](https://www.mongodb.com/docs/manual/reference/operator/aggregation/filter.md#mongodb-expression-exp.-filter to return only elements of the items input array that match the condition specified using the [$and](https://www.mongodb.com/docs/manual/reference/operator/aggregation/and.md#mongodb-expression-exp.-and operator. The and operator uses the following operators:[$ifNull](https://www.mongodb.com/docs/manual/reference/operator/aggregation/ifNull.md#mongodb-expression-exp.-ifNull to determine if items.price contains null values and replace null values, if present, with the replacement expression false.; [$gt](https://www.mongodb.com/docs/manual/reference/operator/aggregation/gt.md#mongodb-expression-exp.-gt to check if quantity is greater than 2.; [$in](https://www.mongodb.com/docs/manual/reference/operator/aggregation/in.md#mongodb-expression-exp.-in to check if office exists in the tags array.
db.sales.aggregate(
  {
    "$search": {
      "embeddedDocument": {
        "path": "items",
        "operator": {
          "compound": {
            "must": [
              {
                "range": {
                  "path": "items.quantity",
                  "gt": 2
                }
              },
              {
                "exists": {
                  "path": "items.price"
                }
              },
              {
                "text": {
                  "path": "items.tags",
                  "query": "school"
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    "$limit": 2
  },
  {
    "$project": {
      "_id": 0,
      "storeLocation": 1,
      "items": {
        "$filter": {
          "input": "$items",
          "cond": {
            "$and": [
              {
                "$ifNull": [
                  "$$this.price", "false"
                ]
              },
              {
                "$gt": [
                  "$$this.quantity", 2
                ]
              },
              {
                "$in": [
                  "office", "$$this.tags"
                ]
              }
            ]
          }
        }
      }
    }
  }
)

Output:

[
  {
    storeLocation: 'Austin',
    items: [
      {
        name: 'laptop',
        tags: [ 'electronics', 'school', 'office' ],
        price: Decimal128('753.04'),
        quantity: 3
      },
      {
        name: 'pens',
        tags: [ 'writing', 'office', 'school', 'stationary' ],
        price: Decimal128('19.09'),
        quantity: 4
      },
      {
        name: 'notepad',
        tags: [ 'office', 'writing', 'school' ],
        price: Decimal128('30.23'),
        quantity: 5
      },
      {
        name: 'pens',
        tags: [ 'writing', 'office', 'school', 'stationary' ],
        price: Decimal128('20.05'),
        quantity: 4
      },
      {
        name: 'notepad',
        tags: [ 'office', 'writing', 'school' ],
        price: Decimal128('22.08'),
        quantity: 3
      },
      {
        name: 'notepad',
        tags: [ 'office', 'writing', 'school' ],
        price: Decimal128('21.67'),
        quantity: 4
      }
    ]
  },
  {
    storeLocation: 'Austin',
    items: [
      {
        name: 'notepad',
        tags: [ 'office', 'writing', 'school' ],
        price: Decimal128('24.16'),
        quantity: 5
      },
      {
        name: 'notepad',
        tags: [ 'office', 'writing', 'school' ],
        price: Decimal128('28.04'),
        quantity: 5
      },
      {
        name: 'notepad',
        tags: [ 'office', 'writing', 'school' ],
        price: Decimal128('21.42'),
        quantity: 5
      },
      {
        name: 'laptop',
        tags: [ 'electronics', 'school', 'office' ],
        price: Decimal128('1540.63'),
        quantity: 3
      },
      {
        name: 'pens',
        tags: [ 'writing', 'office', 'school', 'stationary' ],
        price: Decimal128('29.43'),
        quantity: 5
      },
      {
        name: 'pens',
        tags: [ 'writing', 'office', 'school', 'stationary' ],
        price: Decimal128('28.48'),
        quantity: 5
      }
    ]
  }
]

Learn More

To learn more, see [How to Run MongoDB Search Queries Against Fields in Embedded Documents.](https://www.mongodb.com/docs/search/tutorial/embedded-documents-tutorial.md#std-label-embedded-documents-tutorial