Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get data from array in mongoose?

I am new to mongoose node.js and mongoDB, I have a db Schema like

Project:{
    projectName:"String",
    projectManager:"String",
    task:[{
           taskName:"String",
           timetakeninhrs:"String"
    }]
};

So what I want is to get only the details of task with particular task name. I am writing sql script so that you can know what I want :

Select taskname,timetakeninhrs from project where taskName ='DB create';
like image 514
Shrutayu Kale Avatar asked Nov 24 '25 02:11

Shrutayu Kale


1 Answers

The $elemMatch projection operator would come in handy for this:

Project
    .where('task.taskName', 'DB create') // or where('task.taskName').equals('DB create').
    .select({_id: 0, task: {$elemMatch: {'taskName': 'DB create'}})
    .exec(function(err, docs){
        var tasks = docs.map(function(doc){ return doc.task[0]; });
        console.log(tasks[0].taskName); // 'DB create'
        console.log(tasks[0].timetakeninhrs); // '3'
    });

In the above, the where() method acts as a static helper method of the Mongoose model that builds up a query using chaining syntax, rather than specifying a JSON object. So

// instead of writing:
Project.find({ 'task.taskName': 'DB create' }, callback);

// you can instead write:
Project.where('task.taskName', 'DB create');

// or
Project.where('task.taskName').equals('DB create');

and then chain the select() method to project the 'task' array field using $elemMatch. In the exec() method (which executes the query asynchronously), you need to pass in a callback which follows the pattern callback(error, results). What results is depends on the operation: For findOne() it is a potentially-null single document, find() a list of documents, count() the number of documents, update() the number of documents affected, etc. In this case this returns an array of documents in the format:

[
    /* 0 */
    {
        "task" : [ 
            {
                "taskName" : "DB create",
                "timetakeninhrs" : "3"
            }
        ]
    },
    /* 1 */
    {
        "task" : [ 
            {
                "taskName" : "DB create",
                "timetakeninhrs" : "9"
            }
        ]
    }
    /* etc */
]

In your callback you can do a bit of data manipulation to get an object that only has those properties you specified, hence the use of the native JavaScript map() function to create a new array of objects with those fields

like image 64
chridam Avatar answered Nov 26 '25 18:11

chridam