1

I want to use mongoose to find in an array of objects by id.

I have this list:

 {
   "data":[
      {
         "_id":"60ce0ea7eb945a22288fd0ba",
         "parent":"50ce0e44eb945a22288fd0b1",
         "label":"label 1-2",
         "ancestors":[
            {
               "_id":"50ce0e44eb945a22288fd0b1",
               "label":"label 1-1"
            },
            {
               "_id":"40ce077e90c6262bdc21aa44",
               "label":"label 1"
            }
         ]
      },
      {
         "_id":"50ce0e44eb945a22288fd0b1",
         "parent":"60ce077e90c6262bdc21aa55",
         "label":"label 1-1",
         "ancestors":[
            {
               "_id":"40ce077e90c6262bdc21aa44",
               "label":"label 1"
            }
         ]
      },
      {
         "_id":"40ce077e90c6262bdc21aa44",
         "parent":null,
         "label":"label 1",
         "ancestors":[]
      }
   ]
}

This is the schema:

const categorySchema = new mongoose.Schema(
  {
    label: {
      type: String,
      required: true
    },
    parent: {
      type: ObjectId,
      default: null,
      ref: 'category'
    },
    ancestors: [
      {
        _id: {
          type: ObjectId,
          ref: 'category'
        },
        label: String
      }
    ]
  },
  { timestamps: true }
);

I tried to do this:

  async getDescendants(req, res) {
    let { pId } = req.body;
    if (!pId) {
      return res.json({ error: 'All filled must be required' });
    } else {
      try {
        const data = await patternModel
          .find({ 'ancestors._id': pId })
          .select({
            _id: false,
            label: true
          })
          .exec();
   
        if (data) {
          return res.json({ data });
        }
      } catch (err) {
        return res.json({ err: err });
      }
    }
  }

this is my actual result:

{
  "data": []
}

when I change .find({ 'ancestors._id': pId }) to .find({ 'ancestors.label': label }) it works but not for the id.

3
  • have you ever tried ancestors[_id] or ancestors[pId] ?! Commented Jun 19, 2021 at 18:53
  • @Program_Lover I tried .find({ 'ancestors[_id]': pId }) and it did not work. Commented Jun 19, 2021 at 18:57
  • @Program_Lover I added the mongoose schema maybe it will help. Commented Jun 19, 2021 at 20:13

1 Answer 1

1

It is not a simple field. It is an array of subdocuments. Use elemMatch.

Edit: When querying _id fields you will have to wrap convert them into ObjectIds (specific to Mongo).

let newPid = mongoose.Types.ObjectId(pId);

 const data = await patternModel.find({ ancestors: { $elemMatch : { _id: newPid} }  })
.select({ _id: false,label: true })
.exec();
Sign up to request clarification or add additional context in comments.

5 Comments

I tried this .find({ ancestors: { $elemMatch: { _id: pId } } }) and it did not work.
let newPid = mongoose.Types.ObjectId(pId);. Add this and replace pId with newPid in the query.
ty, I imported const mongoose = require('mongoose'); in the top level and It works.
Does it work without mongoose.Types.ObjectId(pId);?
you have a closed brace missing in the find(). can u edit 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.