mongodb 2.1.4(The Node Driver)
I'm currently trying to create a new ObjectID for each message I insert into an array(the array being a subdocument).
I figure this way - All CRUD operations can easily be performed on each message in the array.
For Example:
The "threads" collection(Note- An ObjectId for each message)
{
"_id": ObjectId("1234132413424123"), //A thread id
messages:[
{
_id :ObjectId("134124412341234"),// A message id
"message":"MongoDB is my friend"
},
{
_id :ObjectId("534124412342377"),
"message":"MongoDB is my friend too"
},
...
]
},
{
"_id": ObjectId("22341324134224234"),
messages:[
{
_id :ObjectId("8341244123411235"),
"message":"Something clever"
},
{
_id :ObjectId("134124412342376"),
"message":"blah blah blah"
},
...
]
}
What I'm currently doing right now:
var query = {};
query["_id"] = new ObjectID(threadID);
var update = {$push: {}}; //I write the update object externally just for aesthetics
update.$push["messages"] = newMessage;
var threadsCollection = db.collection('threads');
threadsCollection.findOneAndUpdate(query,update, function (err, result) {
if (err) {
console.log(err);
}
db.close();
});
Problem:
Unlike "insert" for collections, an update with $push does not create a new ObjectId for each message added to the array.
Question:
Is there a standard way of creating an ObjectID during a $push into the child array? Or should we just manually create an ObjectID and add it to the child beforehand?
Not a mongodb
expert but, if I understand you correctly, you wish the _id field of the subdocument to be inserted automatically.
I created threads
db and then inserted the first message
in the messages
collection using the following command:
db.messages.insert({messages:[{_id:ObjectId(), message:"Message 1."}]});
Notice the _id:ObjectId()
field. The result is as follow:
Now that I have an ObjectId(56...)
, I can update that particular record and insert more messages to it. And the command is as follow:
db.messages.update({"_id":ObjectId("56...")},
{$push:{messages:{_id:ObjectId(), message:"I am message 2."}}});
And the above would insert the new message in the collection. See below screenshots:
and finally after a few updates the collection looks as follow:
All the _id fields in the messages
array are automatically generated.
It might not be a good idea to use _id
fields for various reasons. Please Google for more details on whether to use _id as key for subdocuments or not.
I used MongoDB shell version 3.0.6 for the commands.
EDIT 28-01-2016 16:09
Since the above solution was based on MongoDB shell, I decided to do another test using Node.js driver for MongoDB. First of all, I declare ObjectID variable as follow
var ObjectID = require('mongodb').ObjectID;
I will use the ObjectID with document id of the thread to which the message should be inserted as follow in my update
and findOneAndUpdate
function calls
app.get('/insertNewMessage', function(req, res) {
db.collection("messages").findOneAndUpdate({
_id: new ObjectID('56aa3554e90911b64c36a424')
}, {
$push: {
messages: {
_id: new ObjectID(),
message: "From NodeJS with <3 using findOneAndUpdate.Bye."
}
}
}, function(err, result) {
if (err)
res.json(err);
else
res.json(result);
});
});
Tested both and works just fine. See the screenshot below:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With