Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

How can I return only one client per several cases with mongoose populate?

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.

Problem courtesy of: Scott

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.

Solution courtesy of: JohnnyHK

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

How can I return only one client per several cases with mongoose populate?

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×