Reputation: 35
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';
Upvotes: 3
Views: 7174
Reputation: 1246
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);
}
});
});
});
});
Upvotes: 1
Reputation: 103365
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
Upvotes: 1