justasking justasking - 4 months ago 35
Javascript Question

Nested object text search in mongoDB

I am not sure how I am going to solve this problem:

I want to search in a mongoDB collection and return only the nested objects that fits the search query (using text search on all of the fields).

All documents in the collection have this format:

{
arr: [
{
_id: 1,
name: 'Random',
description: 'Hello world'
},
{
_id: 2,
name: 'World',
description: 'This is a random description'
},
{
_id: 3,
name: 'Random',
description: 'Hi'
}
]
}


In this case, if my search query is 'world', then this should be the result:

[
{
_id: 1,
name: 'Random',
description: 'Hello world'
},
{
_id: 2,
name: 'World',
description: 'This is a random description'
},
//... objects from other documents in the collection that fits the query
]


If this is not possible in mongoDB, are there any JavaScript libraries that can achieve this? Would greatly appreciate the help!

Answer

With the aggregation framework it could look like so

db.getCollection('yourCollection').aggregate([
    {
        $unwind: '$arr'
    },
    {
        $match: {
            $or: [
                { 'arr.name': /world/i },
                { 'arr.description': /world/i }
            ]
        }
    },
    {
        $project: {
            _id: '$arr._id',
            name: '$arr.name',
            description: '$arr.description'
        }
    }
])

which will result in the following output for your example data:

{
    "_id" : 1,
    "name" : "Random",
    "description" : "Hello world"
}
{
    "_id" : 2,
    "name" : "World",
    "description" : "This is a random description"
}  

To get a single array with the resulting documents as shown in your question, you can simple chain a toArray() call at the end of the pipeline.