【问题标题】:mongoDB : Creating An ObjectId For Each New Child Added To The Array FieldmongoDB:为添加到数组字段的每个新子项创建一个 ObjectId
【发布时间】:2016-01-28 00:21:25
【问题描述】:

mongodb 2.1.4(节点驱动)

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

我认为这样 - 可以轻松地对数组中的每条消息执行所有 CRUD 操作。

例如:

“线程”集合(注意 - 每条消息都有一个 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"

        },
        ...
    ]
}

我现在在做什么:

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();
});

问题:

与集合的“插入”不同,使用 $push 的更新不会创建 添加到数组中的每条消息的新 ObjectId。

问题:

是否有在 $push into 期间创建 ObjectID 的标准方法 子数组?还是我们应该手动创建一个 ObjectID 并事先将其添加到孩子?

【问题讨论】:

标签: mongodb


【解决方案1】:

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

我创建了threads db,然后使用以下命令将第一个message 插入到messages 集合中:

db.messages.insert({messages:[{_id:ObjectId(), message:"Message 1."}]}); 

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

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

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

上面会在集合中插入新消息。看下面的截图:

最后经过几次更新后,集合如下所示:

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;

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

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);
    });
});

两者都测试过,效果很好。请看下面的截图:

【讨论】:

  • 如果您使用的是节点驱动程序,这里对此解决方案稍作修改。您可以像 newMessage["_id"] = new ObjectID(); 那样附加到将添加到数组中的子对象,然后像这样 threadCollection.findOneAndUpdate(query,{$push:{messages:newMessage}}}); 那样更新集合
  • 我已经在 Google 上搜索过这样做是否是好的做法,但没有得到肯定的答案。
  • 关于这是否是一个好习惯,这可能是一个很好的阅读stackoverflow.com/questions/12211138/…和这个stackoverflow.com/questions/13472589/…
【解决方案2】:

ObjectId.GenerateNewId() 可用于类的构造函数

使用 MongoDB.Bson; 使用 MongoDB.Bson.Serialization.Attributes;

public class test
{
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId test_uid {get; set;}
public string name{get; set;}

public test(){
    test_uid = ObjectId.GenerateNewId();
}

} 

【讨论】:

    【解决方案3】:

    很抱歉违反了协议,但我没有足够的代表来评论主线程。

    我一直在研究如何使用ObjectID() 生成JSON 插入,并且在我的旅行中发现这个解决方案对于索引不是很好。建议的解决方案具有字符串而不是真实对象 ID 的 _id 值 - 即 "56a970405ba22d16a8d9c30e" 与 ObjectId("56a970405ba22d16a8d9c30e") 不同,使用该字符串的索引会变慢。 ObjectId 实际上在内部表示为 16 bytes

    【讨论】:

      猜你喜欢
      • 2021-10-29
      • 2015-02-21
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 2021-01-04
      • 2015-05-13
      • 1970-01-01
      • 2021-08-07
      相关资源
      最近更新 更多