【问题标题】:Creating unique IDs for a few elements on the document - Mongoose为文档上的一些元素创建唯一 ID - Mongoose
【发布时间】:2022-01-09 13:41:15
【问题描述】:

我正在使用 mongoose 创建一个文档,但我找不到为文档上的一些元素创建唯一 ID 的方法。

举个例子:

Document {
_id: ObjectId(...),
title: "Post Title",
comments: [
        { NEEDED_ID: 1, value: "abc"},{ NEEDED_ID: 2, value: "abc"}
],
input: {
isInput: true,
NEEDED_ID: 3,
}
}

希望你能帮帮我。

【问题讨论】:

  • 您是否要创建独特的_id?还是NEEDED_ID 的唯一值?这是数据随机化问题还是 ID 参照完整性问题?
  • @BuzzMoschetti 嗨,感谢您的评论,我说的不是_id,而是一个名为“NEEDED_ID”的键,它应该从 1 开始,一直到最后需要的时间。每次创建新文档时计数都会重置。也许我可以从数据库返回一个带有评论索引的键?
  • 啊。因此,您想创建唯一的 字段名称,例如comments: [ {FLD1:1,value:1},{FLD2:2,value:"abc"] ?
  • @BuzzMoschetti 更像是comments: [ {theSpecialKey:1,value:"a"}, {theSpecialKey:2,value:"b"}]
  • 还是有点不确定。你说“它应该从 1 开始,一直到最后需要的时间”,然后“重置……创建一个新文档”。那么为什么theSpecialKey 一遍又一遍地重复呢?建议:编辑问题并放入 2 个文档,这些文档看起来像您希望它们在创建后的样子。

标签: javascript node.js mongodb mongoose


【解决方案1】:

如果您需要一个自动递增的 id,请检查 mongoDB 中的自动递增:https://www.mongodb.com/basics/mongodb-auto-increment

上面的 mongoDB 文档中带有 Atlas 的示例:

// create collections
db.createCollection("students");
db.createCollection("counters");

// create trigger
exports = async function(changeEvent) {
    var docId = changeEvent.fullDocument._id;
    
    const countercollection = context.services.get("<ATLAS-CLUSTER>").db(changeEvent.ns.db).collection("counters");
    const studentcollection = context.services.get("<ATLAS-CLUSTER>").db(changeEvent.ns.db).collection(changeEvent.ns.coll);
    
    var counter = await countercollection.findOneAndUpdate({_id: changeEvent.ns },{ $inc: { seq_value: 1 }}, { returnNewDocument: true, upsert : true});
    var updateRes = await studentcollection.updateOne({_id : docId},{ $set : {studentId : counter.seq_value}});
    
    console.log(`Updated ${JSON.stringify(changeEvent.ns)} with counter ${counter.seq_value} result : ${JSON.stringify(updateRes)}`);
    };

// Replace <ATLAS-CLUSTER> with your cluster service name.

db.students.insert({
   "name":"Jhon Doe"
});
db.students.insert({
   "name":"David Smith"
});
db.students.insert({
    "name":"Amanda Herny"
});
// get students from atlas
db.students.find().pretty();

如果需要在node中创建随机id,可以使用crypto包。

选项 1:

const crypto = require("crypto");

// create id
const _id = crypto.randomBytes(16).toString("hex");
// '4a82db25ba403269c009db0129a032f3'

选项 2:

const { randomUUID } = require("crypto");

const uuid = randomUUID()  
// 'e92b8088-7fd2-40fd-ad87-2c16cbedfc94'

编辑:关于您的评论,randomUUID() 每次都会生成一个唯一的 ID。如果它不适合您,请仔细检查您的实施。您可以像这样在演示脚本中测试 uuid 生成:

const { randomUUID } = require("crypto");

numberOfIds = 5;

// generate five unique id's
for (let i = 0; i < numberOfIds; i++) {
  const uuid = randomUUID();
  console.log(uuid);

  // prints 5 id's
  // f0151ff5-2656-400f-b4e6-c5549324f8f9
  // a8223ae3-6259-4114-951b-8c12c3d932bf
  // 3a0404fd-6f5a-40d3-9726-c549f6d62ab4
  // 35178ac4-62d5-4654-938e-0ffac378751a
  // 458bf08f-07d2-4849-bf67-6f328ff93109
}

【讨论】:

  • 嘿,感谢您的评论,我使用了 uuid,但它并没有为每个人获得一个新的 id,而是为每个文档获得一个不变的 id,这对我来说不起作用。我什至想创建一个变量并每次都增加它,但它也没有奏效。
  • 嘿,它每次都会创建一个独特的,检查我添加到我的答案中的演示脚本,也许在一个新的环境中尝试它。 + 如果您运行旧版本,可能会更新您的节点版本
  • 您好,我会像您一样尝试,我正在尝试获取索引号而不是长字符串,但目前我找不到这样做的方法,所以我可能会使用您的非常感谢!
  • 再次阅读您的问题,您可能想要一个递增的数字。检查我对 mongoDB 文档的回答中的链接 - 也许这就是你想要的。
  • 我确实看起来像一个解决方案,直到现在还没有看到链接。非常感谢!
猜你喜欢
  • 2011-11-06
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
相关资源
最近更新 更多