1

thanks for reading. I am trying to get a big list of data I have stored in a mongodb database, to display on a frontend, using the mongoose module in NodeJS. I am wondering what's the best way to tackle this problem? My data looks like this...

Collection 1: caves

{ 
    "_id" : ObjectId("564d2f6eb0896138247ff791"), 
    "name" : "ACME Cave", 
    "slug" : "acme-cave",
    "timeCreated" : ISODate("2015-11-19T02:09:50.492+0000"), 
    "address" : {
        "county" : "Somewhere", 
        "state" : "CA", 
        "country" : "USA"
    }
}

Collection 2: locations

{ 
    "_id" : ObjectId("564d2f6fb0896138247ff855"), 
    "latitude" : 54.5793621, 
    "longitude" : -74.9669167, 
    "parent_id" : ObjectId("564d2f6eb0896138247ff791"), <-- matches collection 1
    "timeCreated" : ISODate("2015-11-19T02:09:51.413+0000"),
}
{ 
    "_id" : ObjectId("564d2f6fb0896138247ff855"), 
    "latitude" : 48.5783611, 
    "longitude" : -72.9669167, 
    "parent_id" : ObjectId("564d2f6eb0896138247ff791"), <-- matches collection 1
    "timeCreated" : ISODate("2015-11-19T02:09:51.413+0000"),
}

I would like to merge some of the children fields into the parent like so...

{ 
    "_id" : ObjectId("564d2f6eb0896138247ff791"), 
    "name" : "ACME Cave", 
    "slug" : "acme-cave",
    "timeCreated" : ISODate("2015-11-19T02:09:50.492+0000"), 
    "address" : {
        "county" : "Somewhere", 
        "state" : "NY", 
        "country" : "USA"
    },
    locations: [
    { 
            "_id" : ObjectId("564d2f6fb0896138247ff855"), 
            "latitude" : 54.5793621, 
            "longitude" : -74.9669167, 
            "parent_id" : ObjectId("564d2f6eb0896138247ff791"), <-- matches doc collection 1
            "timeCreated" : ISODate("2015-11-19T02:09:51.413+0000"),
    },
    { 
            "_id" : ObjectId("564d2f6fb0896138247ff855"), 
            "latitude" : 48.5783611, 
            "longitude" : -72.9669167, 
            "parent_id" : ObjectId("564d2f6eb0896138247ff791"), <-- matches doc collection 1
            "timeCreated" : ISODate("2015-11-19T02:09:51.413+0000"),
    }
    ]
}

I have this snippet below which accomplishes this, but it doesn't seem right. Does anyone have any insight into doing this right?

Parent.find({}, {'locations': 1}).stream().on('data', function(parent) {
    // add the location to the parent doc
    Child.find({parent_id: {$in: parent._id}}, {'latitude': 1, 'longitude': 1}, function(err, child) {
      parent.locations = child;
      console.log(parent);
    });
});

This returns the follwing JSON, which is the same as my output..

{ 
    "_id" : ObjectId("564d2f6eb0896138247ff791"), 
    "name" : "ACME Cave", 
    "slug" : "acme-cave",
    "timeCreated" : ISODate("2015-11-19T02:09:50.492+0000"), 
    "address" : {
        "county" : "Somewhere", 
        "state" : "NY", 
        "country" : "USA"
    },
    locations: [
    { 
            "_id" : ObjectId("564d2f6fb0896138247ff855"), 
            "latitude" : 54.5793621, 
            "longitude" : -74.9669167, 
            "parent_id" : ObjectId("564d2f6eb0896138247ff791"), <-- matches doc collection 1
            "timeCreated" : ISODate("2015-11-19T02:09:51.413+0000"),
    },
    { 
            "_id" : ObjectId("564d2f6fb0896138247ff855"), 
            "latitude" : 48.5783611, 
            "longitude" : -72.9669167, 
            "parent_id" : ObjectId("564d2f6eb0896138247ff791"), <-- matches doc collection 1
            "timeCreated" : ISODate("2015-11-19T02:09:51.413+0000"),
    }
    ]
}

I have thought about rolling up these Schemas into 1 collection, but I cannot due to other features I'll be adding to the code, like storing pictures, and edits per children. I don't think using a single collection is wise, because I'll be storing too much information in a document.

Thanks for your help!

1 Answer 1

1

I think that you can use one-to-many with document references model. That is to say, store the location reference (only _id) inside the cave document.

{ 
    "_id" : ObjectId("564d2f6eb0896138247ff791"), 
    "name" : "ACME Cave", 
    "slug" : "acme-cave",
    "timeCreated" : ISODate("2015-11-19T02:09:50.492+0000"), 
    "address" : {
        "county" : "Somewhere", 
        "state" : "NY", 
        "country" : "USA"
    },
    locations: [ 564d2f6fb0896138247ff855, 564d2f6fb0896138247ff855 ]
}
Sign up to request clarification or add additional context in comments.

3 Comments

This isn't a bad idea! I was thinking somewhere along the lines of this, but I kept thinking to myself, what if I have a random location document and I need to get the parent? I could store the parent_id still, I guess. I think this is a bad way to go about it, or maybe it's common to store both in each collection? I come from a strong relational database background and getting my head out of that is been rough.
In MongoDB there are different solutions to your problem . I recommend the following series of articles: 6 Rules of thumb for MongoDB Schema Design.
Thanks for all your help, I've decided to follow your example and store the ObjectIds in the cave documents.

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.