【问题标题】:create a new object Id in mongoDB using node js使用节点 js 在 mongoDB 中创建一个新的对象 ID
【发布时间】:2015-08-04 04:56:31
【问题描述】:

我正在使用下面的代码向 mongodb 插入数据

    router.post('/NewStory', function (req, res) {
var currentObject = { user: userId , story : story , _id:new ObjectID().toHexString() };
        req.db.get('clnTemple').findAndModify({
            query: { _id: req.body.postId },
            update: { $addToSet: { Stories: currentObject } },
            upsert: true
        });
});

如果我删除_id:new ObjectID().toHexString(),此代码可以正常工作

我想在这里实现的是,对于每个新故事,我都希望附加一个唯一的 _id 对象

我做错了什么?

{
    "_id": {
        "$oid": "55ae24016fb73f6ac7c2d640"
    },
    "Name": "some name",
     ...... some other details
    "Stories": [
        {
            "userId": "105304831528398207103",
            "story": "some story"
        },
        {
            "userId": "105304831528398207103",
            "story": "some story"
        }
    ]
}

这是文档模型,我要创建的 _id 用于故事

【问题讨论】:

  • 你不需要这样做mongodb自动创建_id属性作为uniqe id
  • 这个 ObjectID 在哪里初始化

标签: node.js mongodb monk


【解决方案1】:

您不应为此调用.toHexString(),因为您将获得“字符串”而不是ObjectID。字符串占用的空间比ObjectId 的字节多。

var async = require('async'),
    mongo = require('mongodb'),
    db = require('monk')('localhost/test'),
    ObjectID = mongo.ObjectID;


var coll = db.get('junk');

var obj = { "_id": new ObjectID(), "name": "Bill" };

coll.findAndModify(
  { "_id": new ObjectID() },
  { "$addToSet": { "stories": obj } },
  {
    "upsert": true,
    "new": true
  },
  function(err,doc) {
    if (err) throw err;
    console.log(doc);
  }
)

所以这对我来说非常有效。还要注意那里的“新”选项,以便返回修改后的文档,而不是默认的文档的原始形式。

 { _id: 55c04b5b52d0ec940694f819,
   stories: [ { _id: 55c04b5b52d0ec940694f818, name: 'Bill' } ] }

但是这里有一个问题,那就是如果您使用$addToSet 并为每个项目生成一个新的ObjectId,那么这个新的ObjectId 会使所有内容都“独一无二”。所以你会不断地将东西添加到“集合”中。如果您想这样做,也可以是 $push

因此,如果 userIdstory 组合在一起已经使这个“独一无二”,那么请改为这样做:

coll.findAndModify(
  { 
      "_id": docId, 
      "stories": {
          "$not": { "$elemMatch": { "userId": userId, "story": story } }
      }
  },
  { "$push": { 
     "stories": {
         "userId": userId, "story": story, "_id": new ObjectID()
     }
  }},
  {
    "new": true
  },
  function(err,doc) {
    if (err) throw err;
    console.log(doc);
  }
)

因此,测试数组中是否存在唯一元素,如果它们不存在,则将它们附加到数组中。还要注意,在与“upserts”混合时,您不能对数组元素进行“不等式匹配”。您对“更新”文档的测试应该只在主要的“_id”值上。管理数组条目和文档“更新插入”需要在单独的更新操作中进行。不要尝试将两者混合使用,否则您最终会在不打算创建新文档时创建。

【讨论】:

  • 感谢我使用了相同的代码,并且它可以单独删除异步是否会产生重大影响
  • 用户 ID 和故事在我的场景中不会成为唯一键,因为一个用户可能会添加多个故事
  • @vignesh 这就是为什么我说“如果”就是这种情况。不过需要注意的是,通过每次创建一个“新”ObjectId 值,您将取消对$addToSet 的需求。根据定义,添加到数组中的每个“新”项始终是“唯一的”。
  • Stackoverflow 中是否存在错误?我记得看到@Blakes Seven 大约有 4K 点,现在只显示 1?!
【解决方案2】:

顺便说一句,您可以只使用monk 生成ObjectID

var db = monk(credentials.database);

var ObjectID = db.helper.id.ObjectID

console.log(ObjectID()) // generates an ObjectID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-07
    • 2019-08-02
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多