How can I return only one client per several cases with mongoose populate?
Problem
I'm using mongoose populate to try an create one-to-many relationships within my schemas
var clientSchema = new mongoose.Schema({
name: { type: String, required: true },
title: { type: String, default: "N/S" },
birthDate: { type: Date },
ssn: { type: String, default: "N/S" },
spouse: { type: String, default: "N/S" },
notes: { type: String, default: "N/S" },
address: { type: String, default: "N/S" },
city: { type: String, default: "N/S" },
state: { type: String, default: "N/S" },
zip: { type: String, default: "N/S" },
homePhone: { type: String, default: "N/S" },
workPhone: { type: String, default: "N/S" },
mobilePhone: { type: String, default: "N/S" },
fax: { type: String, default: "N/S" },
email: { type: String, default: "N/S" }
});
var caseSchema = mongoose.Schema({
_client: { type: mongoose.Schema.Types.ObjectId, ref: 'Client' },
name: { type: String, required: true },
lead: { type: String },
priority: { type: String },
dateOpened: { type: Date },
dateAccident: { type: Date },
status: { type: String },
sol: { type: Date },
description: { type: String }
});
What I want to be able to do is query the data base to get all cases with a given _client id. I have this working but not the way I want it. As of right now, when I use the populate method from within my route, I'm getting all of the cases with that client id, but I'm also getting all of the clients, even though all of the clients are the exact same. It seem like this is a waste of resources to return the same client for each case. Is there any way to just return the client once, and then all of the related cases with it?
app.get('/cases/:id', function( req, res ) {
Case
.find( { _client: req.params.id } )
.populate('_client')
.exec( function( err, cases ) {
res.send( cases );
});
});
Here's what I'm getting back:
[
{
"_client": {
"name": "John Doe",
"birthDate": null,
"_id": "51705a7ed0ecd0a906000001",
"__v": 0,
"email": "",
"fax": "",
"mobilePhone": "",
"workPhone": "",
"homePhone": "",
"zip": "",
"state": "",
"city": "",
"address": "",
"notes": "",
"spouse": "",
"ssn": "",
"title": "Mr"
},
"name": "test",
"lead": "",
"priority": "",
"dateOpened": null,
"dateAccident": null,
"status": "",
"sol": null,
"description": "",
"_id": "5170679df8ee8dd615000001",
"__v": 0
},
{
"_client": {
"name": "John Doe",
"birthDate": null,
"_id": "51705a7ed0ecd0a906000001",
"__v": 0,
"email": "",
"fax": "",
"mobilePhone": "",
"workPhone": "",
"homePhone": "",
"zip": "",
"state": "",
"city": "",
"address": "",
"notes": "",
"spouse": "",
"ssn": "",
"title": "Mr"
},
"name": "newest case",
"lead": "",
"priority": "",
"dateOpened": null,
"dateAccident": null,
"status": "",
"sol": null,
"description": "",
"_id": "517067d8806f060b16000001",
"__v": 0
},
{
"_client": {
"name": "John Doe",
"birthDate": null,
"_id": "51705a7ed0ecd0a906000001",
"__v": 0,
"email": "",
"fax": "",
"mobilePhone": "",
"workPhone": "",
"homePhone": "",
"zip": "",
"state": "",
"city": "",
"address": "",
"notes": "",
"spouse": "",
"ssn": "",
"title": "Mr"
},
"name": "adding new case",
"lead": "Me",
"priority": "Urgent",
"dateOpened": null,
"dateAccident": null,
"status": "",
"sol": null,
"description": "",
"_id": "51709a16806f060b16000002",
"__v": 0
}
]
This just doesn't seem right to send all of this bloat to my view to be rendered. Should I even be using populate for one-to-many like this? All of the examples that I see on mongoose.com are one-to-one, with the exception of embedded documents.
Solution
If you don't want the client repeated for each case, you'd be better off separately querying for the client and then combining that result with the result of your Case
query (without the populate
) in whatever way you need.
BTW, '/cases/:id'
is a pretty confusing URL for getting cases by client id and not case id.
Discussion
View additional discussion.