0

I have a Chapter schema like this:

const ChapterSchema = new Schema({
    title: {
        type: String,
        required: [true, 'Chapter title is required']
    },
    topics: { type: [TopicSchema] }
})

So, there is a topics array as sub-documents of Chapter. I want to get a particular topic by its _id from Chapter. For that I've tried this query below:

let data = await Chapter.findOne({ "topics._id": _id })
return res.json(data)

But it returns a whole chapter of this topic with topic sibling like this:

{
    "_id": "5e504271ee36f61ba8d76f37",
    "title": "Roshayon Chapter 2",
    "topics": [
        {
            "_id": "5e52bdf994b60b4c540cab33",
            "title": "topic 4",
            "intro": "<p><b>This text is bold</b></p><p><i>This text is italic</i></p><p>This is<sub> subscript</sub> and <sup>superscript</sup></p>"
        },
        {
            "_id": "5e52bdf994b60b4c540cab34",
            "title": "topic 5",
            "intro": "<p><b>This text is bold</b></p><p><i>This text is italic</i></p><p>This is<sub> subscript</sub> and <sup>superscript</sup></p>"
        }
    ]
}

I don't need whole chapter as above. I just need a single topic object which I am looking for by its id. How can I able to get

Expected result:

        {
            "_id": "5e52bdf994b60b4c540cab34",
            "title": "topic 5",
            "intro": "<p><b>This text is bold</b></p><p><i>This text is italic</i></p><p>This is<sub> subscript</sub> and <sup>superscript</sup></p>"
        }

1 Answer 1

1

You need to use $elemMatch while projecting so it gives us the matching array rec ord.

something like this should work

let data = await Chapter.findOne({ "topics._id": _id }, {_id: 0, topics: {$elemMatch: {_id: _id}}});

If you need to get the just object, you can use aggregate and use following query

await Chapter.aggregate([
    {$match: {'topics._id': "5e52bdf994b60b4c540cab33"}},
    {$project: {
        topics: {$filter: {
            input: '$topics',
            as: 'topic',
            cond: {$eq: ['$$topic._id', '5e52bdf994b60b4c540cab33']}
        }},
        _id: 0
    }}
]).unwind("topics").exec()

Hope it helps.

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

4 Comments

It returns this: {"topics": []}
apologies, updated my answer. removed the extra topics which wasn't required. Please try now
Now, It's working but the problem is I'm getting the single topic object in topics array. Can I get only that topic?
@AnwarulIslam this might be the way aggregate is being used. I am not too familiar with mongoose. I have tried that query directly on mongod and it works fine. Updated it as per this - mongoosejs.com/docs/api/aggregate.html Try now.

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.