Nguyen Van Quang
Nguyen Van Quang

Reputation: 43

How to get size of array embedded array mongoose?

I have a category collection and I want to get category by id with some options. This is collection's structure in database.

[
  {
    "_id": "5d67296bf35b984e74486924",
    "name": "Dinrk",
    "images": [],
    "recipes": [
      {
        "name": "Coffee",
        "time": 20,
        "img": "https://google.com/image-example.jpg",
        "des": "This is description",
        "serving": 2,
        "components": [
          {
            "name": "Dink 1",
            "quantity": "1"
          },
          {
            "name": "Dink 2",
            "quantity": "1"
          },
          {
            "name": "Dink 2",
            "quantity": "1"
          }
        ],
        "cook_steps": [
          {
            "des": "This is description",
            "pictures": []
          },
          {
            "des": "This is description",
            "pictures": []
          }
        ]
      },
      {
        "name": "Coffee",
        "time": 20,
        "img": "https://google.com/image-example.jpg",
        "des": "This is description",
        "serving": 2,
        "components": [
          {
            "name": "Dink 1",
            "quantity": "1"
          },
          {
            "name": "Dink 2",
            "quantity": "1"
          }
        ],
        "cook_steps": [
          {
            "des": "This is description",
            "pictures": []
          },
          {
            "des": "This is description",
            "pictures": []
          }
        ]
      }
    ]
  },
  {
    "_id": "5d67296bf35b984e74486435555",
    "name": "Cake",
    "images": [],
    "recipes": [
      {
        "name": "Cake",
        "time": 20,
        "img": "https://google.com/image-example.jpg",
        "des": "This is description",
        "serving": 2,
        "components": [
          {
            "name": "Cake 1",
            "quantity": "1"
          },
          {
            "name": "Cake 2",
            "quantity": "1"
          },
          {
            "name": "Cake 2",
            "quantity": "1"
          }
        ],
        "cook_steps": [
          {
            "des": "This is description",
            "pictures": []
          },
          {
            "des": "This is description",
            "pictures": []
          }
        ]
      },
      {
        "name": "Coffee",
        "time": 20,
        "img": "https://google.com/image-example.jpg",
        "des": "This is description",
        "serving": 2,
        "components": [
          {
            "name": "Cake 1",
            "quantity": "1"
          }
        ],
        "cook_steps": [
          {
            "des": "This is description",
            "pictures": []
          },
          {
            "des": "This is description",
            "pictures": []
          }
        ]
      }
    ]
  }
]

This is my code to try categoryId = "5d67296bf35b984e74486924"

Category.aggregate([
            {
                $match: {'_id': categoryId}
            },
            {
                $unwind: '$recipes'
            },
            {
                $project: {
                    'total_components': {'$size': '$recipes.components'},
                    'total_cook_steps': {'$size': '$recipes.cook_steps'}
                }
            }
        ]).then(function(data) {

}, function(err) {

})

And expected result is

{
    "_id": "5d67296bf35b984e74486924",
    "name": "Dinrk",
    "images": [],
    "recipes": [
      {
        "name": "Coffee",
        "time": 20,
        "img": "https://google.com/image-example.jpg",
        "des": "This is description",
        "serving": 2,
        "total_components": 3,
        "total_cook_steps": 2
      },
      {
        "name": "Coffee",
        "time": 20,
        "img": "https://google.com/image-example.jpg",
        "des": "This is description",
        "serving": 2,
        "total_components": 2,
        "total_cook_steps": 2
      }
    ]
  }

But when I run above my code, result is [].

If you understand my problem, please help me. I have search a lot, but not found solution. So I want to ask everyone. Thankyou so much.

Upvotes: 1

Views: 176

Answers (1)

chridam
chridam

Reputation: 103365

Your query is not giving you the desired result since Mongoose does not auto-cast the 24 char hex string to ObjectId in its aggregate pipeline since $project and $group can change the schema in surprising ways that it becomes hard to infer what should be an ObjectId.

You need to manually convert the categoryId string to ObjectId using the mongoose.Types.ObjectId method.

Compute the new fields within a $map operator instead of $unwind as this allows you an aggregate operation with fewer pipeline steps

Category.aggregate([
    { '$match': { '_id': mongoose.Types.ObjectId(categoryId) } },
    { '$addFields': {
        'recipes': {
            '$map': {
                'input': '$recipes',
                'in': {
                    'name': '$$this.name',
                    'time': '$$this.time',
                    'img': '$$this.img',
                    'des': '$$this.des',
                    'serving': '$$this.serving',
                    'total_components': { '$size': '$$this.components' },
                    'total_cook_steps': { '$size': '$$this.cook_steps' }
                }
            }
        }
    } }
]).then(function(data) {

}, function(err) {

})

Upvotes: 1

Related Questions