Search code examples
node.jsmongodbmongoosefindsubdocument

Querying a sub document of a sub document in mongoose


Inside my parent I have many childs and in one of them childs they also have many sub childs, I need to return the sub childs from a specific child.

exports.test = (req, res) => {
    Forum.find({title: req.params.id}).then(record => {
        console.log(record);
    })
};

The code here returns the following when I insert the News & Announcement url param which is correct:

_id: 5e7bf52ebb5b2b09fb46e29f,
title: 'News & Announcements',
property: 'ACP',
position: 1,
visible: true,
topics: [ [Object], [Object], [Object] ],
__v: 5 } ]

I then want to access the topics and return a specific topic - finding it by a name/title as I did above, how would I do this?


Solution

  • If this topics field is an array of objects and each object contains the name and title, then you can search for the topic you want, just add that to the object you passed to the find query

    for example, If you need to query for some topic with name 'My Topic', then the query should be

    Forum.find({ title: req.params.id, 'topics.name': 'My Topic' })
    

    this will narrow down the results of the query but if there are some other topics with different names in the same forum, they will be come with you in the query

    for example, if some forum has the following info:

    {
        _id: ObjectId("5e7bf52ebb5b2b09fb46e29f"),
        title: 'News & Announcements',
        property: 'ACP',
        position: 1,
        visible: true,
        topics: [
            {
                name: 'Topic 1',
                title: 'Title 1'
            }, {
                name: 'Topic 2',
                title: 'Title 2'
            }, {
                name: 'My Topic',
                title: 'My Title'
            }
        ],
    }
    

    and you search for the topic 'My Topic' only in this forum, all the topics array will be returned from the query, as the search is done per documents

    so you have to do some javaScript trick after finishing the query to get only the topic that has the name you wanted

    var myTopic = record.ropics.filter(topic => topic.name === 'My Topic'} 
    

    this will return the topic you wanted only