Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB arrays vs objects

Lets say I want to maintain a list of items per user (in MongoDB with Mongoose ODM in Node.js environment) and later query to see if an item is owned by a user. For example, I want to store all of the favorite colors of each user, and later see if a specific color is owned by a specific user. It seems to me that it would be better to store the colors as an embedded object within the user document, rather than an array within the user document. The reason why is that it seems more efficient to check to see if a color exists in an object as I can just check to see if the object property exists:

if(user.colors.yellow){
  //true case
} else {
  //false case
}

Versus an array where I have to iterate through the entire array to see if the color exists somewhere in the array:

for (var i = 0; i < user.colors.length; i++) {
  if(user.colors[i] === "yellow"){
    //true case
  } else {
    //false case
  }
}

However, from many of the examples I've seen online, it seems like using arrays for this type of thing is fairly prevalent. Am I missing something? What are the pros/cons, and best way to do this?

like image 379
Ryan Ogle Avatar asked Sep 09 '12 02:09

Ryan Ogle


2 Answers

You don't have to use a for-loop if the colors are stored as an array. You can just use indexOf, as in:

if(user.colors.indexOf("yellow") != -1){
   //true case
}

That said, it really shouldn't matter either way whether you use an embedded document or array; it's not like one or the other is going to give a huge performance advantage.

like image 124
McGarnagle Avatar answered Oct 26 '22 22:10

McGarnagle


You frequently see embedded arrays used to store this type of information in MongoDB collections because if you add an index to the array property they're efficient to query and they use a natural syntax. In this case something like the following (assuming a users collection that contains a colors array property):

db.users.find({id: 1, colors: 'yellow'})

If you did this with individual color properties you'd have a more awkward looking query like this and you'd have to separately index each color (instead of just colors like you would above):

db.users.find({id: 1, 'colors.yellow': true})
like image 33
JohnnyHK Avatar answered Oct 26 '22 22:10

JohnnyHK