user2544102
user2544102

Reputation: 91

How to use $elementMatch in aggregate

How to use child $elementMatch in aggregate? I need to return this ' Grand Child" element from the mongo: productCode = "aaaa" Size = "41" and ware "LAX"

{
   "_id" : ObjectId("5db72c636309f84479ec0c80"),
   "ware" : "LAX",
   "amount" : 100
}

Here is the full object:

{
  "_id": ObjectId("5db72c636309f84479ec0c7b"),
  "productCode": "aaaa",
  "brand": "Nike",
  "image": "some.jpg",
  "sizes": [
    {
      "_id": ObjectId("5db72c636309f84479ec0c7e"),
      "size": "41",
      "wares": [
        {
          "_id": ObjectId("5db72c636309f84479ec0c80"),
          "ware": "LAX",
          "amount": 100
        },
        {
          "_id": ObjectId("5db72c636309f84479ec0c7f"),
          "ware": "NYC",
          "amount": 7
        }
      ]
    },
    {
      "_id": ObjectId("5db72c636309f84479ec0c7c"),
      "size": "42",
      "wares": [
        {
          "_id": ObjectId("5db72c636309f84479ec0c7d"),
          "ware": "LAX",
          "amount": 16
        }
      ]
    }
  ]
}

This is what I tried already, but I just get back empty array :(

let id = "aaaa";
let size = "41";
let ware = "LAX";
Product.aggregate(
  [
    { $unwind: "$sizes.wares" },
    {
      $match: {
        productCode: id,
        "sizes.size": size,
        "sizes.wares": { $elemMatch: { ware: ware } }
      }
    }
  ],
  (err, products) => {
    if (err) {
      return res.status(422).send(err);
    }
    return res.json(products);
  }
);

Upvotes: 1

Views: 701

Answers (1)

SuleymanSah
SuleymanSah

Reputation: 17888

You can use the following aggregation.

First we match with productCode, then unwinding sizes and sizes.wares, then applying size and ware match, and lastly using $replaceRoot to promote embedded document to the root.

Note: replaceRoot works for MongoDb version 3.4 or newer.

Product.aggregate([
  {
    $match: {
      productCode: "aaaa"
    }
  },
  {
    $unwind: "$sizes"
  },
  {
    $unwind: "$sizes.wares"
  },
  {
    $match: {
      "sizes.size": "41",
      "sizes.wares.ware": "LAX"
    }
  },
  {
    $replaceRoot: {
      newRoot: "$sizes.wares"
    }
  }
])

Result:

[
  {
    "_id": ObjectId("5db72c636309f84479ec0c80"),
    "amount": 100,
    "ware": "LAX"
  }
]

Playground:

https://mongoplayground.net/p/rD74iw76a6D

Upvotes: 2

Related Questions