Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose adds _id to all nested objects

Tags:

When creating a document with nested objects (e.g. an array of objects), each object is given its own _id. For example, my schema looks like this:

mongoose = require "mongoose"  Schema = mongoose.Schema  schema = new Schema   name:     type: String     required: true     unique: true     trim: true    lists: [     list:       type: Schema.Types.ObjectId       required: true       ref: "List"     allocations: [       allocation:         type: Number         required: true     ]   ]    createdAt:     type: Date     default: Date.now    updatedAt:     type: Date  # Ensure virtual fields are serialised. schema.set "toJSON",   virtuals: true  exports = module.exports = mongoose.model "Portfolio", schema 

Every object in the lists array is given an _id, as is every allocation object in the lists.allocations array, when documents are eventually created. This seems like overkill and bloats the document, but is there a reason MongoDB (or Mongoose) needs the document to contain this additional information? If not, I'd like to prevent it from happening so that the only _id is on the root document.

Furthermore, Mongoose automatically creates a virtual id for _id, which I need because my client code expects a field id. This is why I'm having virtuals returned with JSON. However, because there are _id fields all throughout the document, not just at the root, this virtual duplicates all of them. If there is no way to prevent the additional _id fields, how can I get a virtual to only apply only to the root document _id? Or if there is a better way to do what I'm trying to do with it, what would it be?

like image 427
neverfox Avatar asked Jun 02 '13 10:06

neverfox


People also ask

Is Mongoose _ID unique?

yes, the unique: true index guarantees it "in this one collection" - the algorithm "almost" guarantees it universally.

How do I update a nested array in MongoDB?

Update Nested Arrays in Conjunction with $[]The $[<identifier>] filtered positional operator, in conjunction with the $[] all positional operator, can be used to update nested arrays. The following updates the values that are greater than or equal to 8 in the nested grades. questions array if the associated grades.

Does Mongoose auto generate ID?

_id field is auto generated by Mongoose and gets attached to the Model, and at the time of saving/inserting the document into MongoDB, MongoDB will use that unique _id field which was generated by Mongoose.


1 Answers

I have figured out a way to solve both issues with the same technique: by using explicit schemas for each nested object type and setting their _id and id options to false. It seems that when nesting objects that you define "inline", Mongoose creates schemas for each of those objects behind the scenes. Since the default for a schema is _id: true and id: true, they will get an _id as well as have a virtual id. But by overriding this with an explicit schema, I can control the _id creation. More code, but I get what I want:

mongoose = require "mongoose"  Schema = mongoose.Schema  AllocationSchema = new Schema   allocation:     type: Number     required: true ,   _id: false    id: false  mongoose.model "Allocation", AllocationSchema  ListsSchema = new Schema   list:     type: Schema.Types.ObjectId     required: true     ref: "List"   allocations: [AllocationSchema] ,   _id: false    id: false  mongoose.model "Lists", ListsSchema  PortfolioSchema = new Schema   name:     type: String     required: true     unique: true     trim: true    lists: [ListsSchema]    createdAt:     type: Date     default: Date.now    updatedAt:     type: Date 
like image 95
neverfox Avatar answered Sep 16 '22 18:09

neverfox