3

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';

2 Answers 2

1

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

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

Comments

1

i create this example that can help you:

var async=require('async');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var uri = 'mongodb://localhost/myDb';
mongoose.connect(uri);

// define a schema
var ProjectSchema = new Schema({
    projectName: "String",
    projectManager: "String",
    task: [{
        taskName: "String",
        timetakeninhrs: "String"
    }]
});

// compile our model
var Project = mongoose.model('Project', ProjectSchema);

// create a documents
var Project01 = new Project({
    projectName: "Project01",
    projectManager: "Manager01",
    task: [{
        taskName: "tsk01_Project01",
        timetakeninhrs: "1111-1111"
    }, {
        taskName: "tsk02_Project01",
        timetakeninhrs: "1111-2222"
    }, {
        taskName: "tsk03_Project01",
        timetakeninhrs: "1111-3333"
    }, {
        taskName: "tsk04_Project01",
        timetakeninhrs: "1111-4444"
    }]
});

var Project02 = new Project({
    projectName: "Project02",
    projectManager: "Manager02",
    task: [{
        taskName: "tsk01_Project02",
        timetakeninhrs: "2222-1111"
    }, {
        taskName: "tsk02_Project02",
        timetakeninhrs: "2222-2222"
    }, {
        taskName: "tsk03_Project02",
        timetakeninhrs: "2222-3333"
    }, {
        taskName: "tsk04_Project02",
        timetakeninhrs: "2222-4444"
    }]
});

//delete existing documents and create them again
Project.remove({}, function() {
    Project01.save(function() {
        Project02.save(function() {
            //for example we find taskName: "tsk03_Project02"
            Project.find({'task': {$elemMatch: {taskName: "tsk03_Project02"}}},'task.taskname task.timetakeninhrs',function(err, docs) {
                if (!err) {
                    console.log(docs);
                }
            });
        });
    });
});

Comments

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.