I am creating a structure like this in Mongoose:
var Access = new Schema({
userId : { type: ObjectId, unique: true },
key : { type: String, index: true },
isOwner : { type: Boolean, index: true },
});
mongoose.model('Access', Access);
var Workspace = new Schema({
name : { type: String, lowercase: true, unique: true},
activeFlag : Boolean,
settings : {
welcomeMessage : String,
invoiceTemplate : String,
longName : String,
defaultCountry : String,
countryId : { type: ObjectId, index: true },
},
access : [ Access ],
});
mongoose.model('Workspace', Workspace);
After adding some documents, I see the result:
{ "activeFlag" : true,
"name" : "w7",
"_id" : ObjectId("5036131f22aa014c32000006"),
"access" : [
{ "user": "merc",
"key" : "673642387462834",
"isOwner" : true,
"_id" : ObjectId("5036131f22aa014c32000007")
}
],
"__v" : 0
}
I am confused by that _id
in the sub-document, which doesn't seem to happen if I add just it as a sub-structure rather than a sub-schema.
So questions:
1)
Where does that _id
come from? Is Mongoose's driver doing it? If so, how can I reach the same behaviour using straight Mongodb? Just by adding an ObjectId field?
2) When would you use a sub-document, and when would you use just a data structure?
3) I haven't gotten started with the serious part of my web application yet. However, wouldn't that ID there be really, and I mean really useful in case you are allowing JsonRest access to a sub-record in a document for example?
Thank you as ever!
Merc.
EDIT: Removed data duplication piece of answer based on comments below.
To answer your other question, how to replicate this in MongoDB itself, you could create that document as follows:
db.foo.insert(
{ "activeFlag" : true,
"name" : "w7",
"access" : [
{ "userId" : ObjectId(),
"key" : "673642387462834",
"isOwner" : true,
"_id" : ObjectId()
}
],
"__v" : 0
})
To explain, the _id in the root document is implied - it will be added by MongoDB if not specified. However, to get _id into the sub-document, you have to manually specify it by calling the ObjectId() function. My doc looked like this:
db.foo.find().pretty()
{
"_id" : ObjectId("50375bd0cee59c8561829edb"),
"activeFlag" : true,
"name" : "w7",
"access" : [
{
"userId" : ObjectId("50375bd0cee59c8561829ed9"),
"key" : "673642387462834",
"isOwner" : true,
"_id" : ObjectId("50375bd0cee59c8561829eda")
}
],
"__v" : 0
}