MongoDB - Query an Array of Embedded Documents

MongoDB

mongodb logo - tutorial - dyclassroom

In this MongoDB tutorial we will learn to query an array of embedded documents.

Login to your MongoDB server and insert the following documents.

For this tutorial I will insert the documents in the books collection.

> db.books.insertMany([
  {
    "title": "The C Programming Language",
    "author": ["Brian Kernighan", "Dennis Ritchie"],
    "inventory": [
      { "warehouse": "W1", "qty": 3000 },
      { "warehouse": "W2", "qty": 750 }
    ]
  },
  {
    "title": "MongoDB in Action",
    "author": ["Kyle Banker"],
    "inventory": [
      { "warehouse": "W2", "qty": 100 },
      { "warehouse": "W3", "qty": 1500 }
    ]
  },
  {
    "title": "Node.js in Action",
    "author": ["Marc Harter", "Nathan Rajlich", "T. J. Holowaychuk", "Mike Cantelon"],
    "inventory": [
      { "warehouse": "W1", "qty": 100 },
      { "warehouse": "W3", "qty": 250 }
    ]
  }
]);

Select based on exact match of embedded document in an array

In the following example we are fetching all the documents having the exact embedded document { "warehouse": "W1", "qty": 100 } in the inventory array.

Note! The field order is important i.e. the first field of the embedded document must be "warehouse" and must have value "W1" and the second field of the embedded document must be "qty" and must have value 100.

> db.books.find({ "inventory": { "warehouse": "W1", "qty": 100 } }).pretty();



{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c121"),
  "title" : "Node.js in Action",
  "author" : [
    "Marc Harter",
    "Nathan Rajlich",
    "T. J. Holowaychuk",
    "Mike Cantelon"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 100
    },
    {
      "warehouse" : "W3",
      "qty" : 250
    }
  ]
}

If we change the field order of the embedded document in the query then we will not get the result.

In the following query we are changing the field order of the embedded document to { "qty": 100, "warehouse": "W1" } and it gives us no result.

> db.books.find({ "inventory": { "qty": 100, "warehouse": "W1" } }).pretty();

Select based on a field of the embedded document in an array

In the following example we are fetching all the documents having value "W1" for the "warehouse" field in one of the embedded document in the "inventory" array.

> db.books.find({ "inventory.warehouse": "W1" }).pretty();


{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c11f"),
  "title" : "The C Programming Language",
  "author" : [
    "Brian Kernighan",
    "Dennis Ritchie"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 3000
    },
    {
      "warehouse" : "W2",
      "qty" : 750
    }
  ]
}
{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c121"),
  "title" : "Node.js in Action",
  "author" : [
    "Marc Harter",
    "Nathan Rajlich",
    "T. J. Holowaychuk",
    "Mike Cantelon"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 100
    },
    {
      "warehouse" : "W3",
      "qty" : 250
    }
  ]
}

In the following example we are fetching all the documents having value greater that 300 for the field "qty" for one of the embedded document in the "inventory" array.

> db.books.find({ "inventory.qty": { $gt: 300 } }).pretty();


{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c11f"),
  "title" : "The C Programming Language",
  "author" : [
    "Brian Kernighan",
    "Dennis Ritchie"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 3000
    },
    {
      "warehouse" : "W2",
      "qty" : 750
    }
  ]
}
{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c120"),
  "title" : "MongoDB in Action",
  "author" : [
    "Kyle Banker"
  ],
  "inventory" : [
    {
      "warehouse" : "W2",
      "qty" : 100
    },
    {
      "warehouse" : "W3",
      "qty" : 1500
    }
  ]
}

Select based on multiple query conditions on embedded document fields

In the following example we are fetching all the documents having "qty" field set to greater than 100 and "warehouse" field set to "W1".

> db.books.find({ "inventory": { $elemMatch: { "qty": { $gt: 100 }, "warehouse": "W1" } } }).pretty();


{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c11f"),
  "title" : "The C Programming Language",
  "author" : [
    "Brian Kernighan",
    "Dennis Ritchie"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 3000
    },
    {
      "warehouse" : "W2",
      "qty" : 750
    }
  ]
}

In the following example we are fetching all the documents having "qty" field set to value greater than 100 for any one of the embedded document.

> db.books.find({ "inventory": { $elemMatch: { "qty": { $gt: 100 } } } }).pretty();



{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c11f"),
  "title" : "The C Programming Language",
  "author" : [
    "Brian Kernighan",
    "Dennis Ritchie"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 3000
    },
    {
      "warehouse" : "W2",
      "qty" : 750
    }
  ]
}
{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c120"),
  "title" : "MongoDB in Action",
  "author" : [
    "Kyle Banker"
  ],
  "inventory" : [
    {
      "warehouse" : "W2",
      "qty" : 100
    },
    {
      "warehouse" : "W3",
      "qty" : 1500
    }
  ]
}
{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c121"),
  "title" : "Node.js in Action",
  "author" : [
    "Marc Harter",
    "Nathan Rajlich",
    "T. J. Holowaychuk",
    "Mike Cantelon"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 100
    },
    {
      "warehouse" : "W3",
      "qty" : 250
    }
  ]
}

If the following example we are selecting all documents that have "qty" field set to value greater than or equal to 200 or "warehouse" field set to value "W1".

> db.books.find({ "inventory.qty": { $gte: 200 }, "inventory.warehouse": "W1" }).pretty();



{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c11f"),
  "title" : "The C Programming Language",
  "author" : [
    "Brian Kernighan",
    "Dennis Ritchie"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 3000
    },
    {
      "warehouse" : "W2",
      "qty" : 750
    }
  ]
}
{
  "_id" : ObjectId("5d2d9afd81a3cd0a9239c121"),
  "title" : "Node.js in Action",
  "author" : [
    "Marc Harter",
    "Nathan Rajlich",
    "T. J. Holowaychuk",
    "Mike Cantelon"
  ],
  "inventory" : [
    {
      "warehouse" : "W1",
      "qty" : 100
    },
    {
      "warehouse" : "W3",
      "qty" : 250
    }
  ]
}