1

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.

1

1 Answer 1

1

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) {

})
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, it's worked. Thank you so much. I really appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.