mongoDB:为每个添加到数组字段的新子项创建一个ObjectId

Nic*_*eda 8 mongodb

mongodb 2.1.4(节点驱动程序)

我正在尝试为插入到数组中的每条消息创建一个新的ObjectID(该数组是一个子文档).

我这样想 - 可以轻松地对阵列中的每条消息执行所有CRUD操作.

例如:

"threads"集合(注意 - 每条消息的ObjectId)

{
    "_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"

        },
        ...
    ]
}
Run Code Online (Sandbox Code Playgroud)

我现在正在做的事情:

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();
});
Run Code Online (Sandbox Code Playgroud)

问题:

与集合的"insert"不同,使用$ push的更新不会为添加到数组的每条消息创建新的ObjectId.

题:

在$ push进入子数组期间是否存在创建ObjectID的标准方法?或者我们应该手动创建一个ObjectID并事先将其添加到孩子身上?

Raf*_*Raf 11

不是mongodb专家,但是,如果我理解正确,您希望自动插入子文档的_id字段.

我创建了threadsdb,然后使用以下命令将第一个插入messagemessages集合中:

db.messages.insert({messages:[{_id:ObjectId(), message:"Message 1."}]}); 
Run Code Online (Sandbox Code Playgroud)

注意该_id:ObjectId()字段.结果如下:

在此输入图像描述

现在我有了ObjectId(56...),我可以更新该特定记录并向其中插入更多消息.命令如下:

db.messages.update({"_id":ObjectId("56...")}, 
{$push:{messages:{_id:ObjectId(), message:"I am message 2."}}});
Run Code Online (Sandbox Code Playgroud)

以上将在集合中插入新消息.见下面的截图:

在此输入图像描述

最后经过一些更新后,该集合看起来如下:

在此输入图像描述

messages数组中的所有_id字段都是自动生成的.

_id出于各种原因使用字段可能不是一个好主意.有关是否使用_id作为子文档的密钥的更多详细信息,请谷歌.

我使用MongoDB shell 3.0.6版命令.

编辑28-01-2016 16:09

由于上面的解决方案基于MongoDB shell,我决定使用Node.js驱动程序为MongoDB做另一个测试.首先,我声明ObjectID变量如下

var ObjectID = require('mongodb').ObjectID;
Run Code Online (Sandbox Code Playgroud)

我将使用ObjectID和消息应该插入到的线程的文档ID,如下所示我updatefindOneAndUpdate函数调用

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);
    });
});
Run Code Online (Sandbox Code Playgroud)

经过测试,效果很好.请参见下面的截图:

在此输入图像描述