Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's best practice "joining" a bunch of values in mongoose/mongodb without populate

Let me start off by stating that I'm aware of the populate method that mongoose offers, but since my work has decided to move to native mongodb drivers in the future, I can no longer rely on populate to avoid work for myself latter on.

If I have two collections of Documents

People
{_id:1, name:Austin}
{_id:2, name:Doug}
{_id:3, name:Nick}
{_id:4, name:Austin}

Hobbies:
{Person: 1,  Hobby: Cars}
{Person:1, Hobby: Boats}
{Person:3, Hobby: Chess}
{Person:4, Hobby: Cars}

How should I go about joining each document in people with Hobbies. Ideally I would prefer to only have to call the database twice once to get the people and the second time to get the hobbies, and then return to the client app objects with them joined toeghter.

like image 736
Austin Davis Avatar asked May 23 '14 16:05

Austin Davis


People also ask

What is the use of populate in mongoose?

Mongoose Populate() Method. In MongoDB, Population is the process of replacing the specified path in the document of one collection with the actual document from the other collection.

Does mongoose populate use lookup?

Mongoose's populate() method does not use MongoDB's $lookup behind the scenes. It simply makes another query to the database. Mongoose does not have functionalities that MongoDB does not have. populate() just makes two or more queries.

What is the difference between schema and model in mongoose?

A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.

Is mongoose good for MongoDB?

Mongoose, a neat ODM library for MongoDB used in Node. js projects, has plenty of useful features that make developers' lives easier. It manages relationships between data, has schema validation, and overall allows coding 3-5 times faster.


1 Answers

It depends on what is your primary concern. Generally, I would say to embed the hobbies into the People, like:

{
  "_id":1,
  "name":"Austin",
  "hobbies": [
    "Cars","Boats"
  ]
},
{
  "_id":2,
  "name":"Doug",
  "hobbies": []
},

{
  "_id":3,
  "name":"Nick",
  "hobbies": [
    "Chess"
  ]
},

{
  "_id":4,
  "name":"Austin",
  "hobbies": [
    "Cars"
  ]
}

which would give you the possibility of using a multi keyed index on hobbies and allow queries like this:

db.daCollection.find({"hobbies":"Cars"})

which would return both Austins as complete documents. Yes, I know that there would be a lot of redundant entries. If you would try to prevent that, could model it like this:

{
  "_id": 1,
  "name":"Cars"
},...

{
  "_id":1,
  "name":"Austin",
  "hobbies": [
    1, ...
  ]
}

which would need an additional index on the name field of the hobby to be efficient. So when you would want to find every person which is into cars, you would need to find the _id and query for it like

db.person.find({"hobbies":1})

I think it is easier, more intuitive and for most use cases faster if you use the embedding.

like image 88
Markus W Mahlberg Avatar answered Sep 21 '22 19:09

Markus W Mahlberg