【问题标题】:How to generate unique id for each entry in mongoDB?如何为 mongoDB 中的每个条目生成唯一 id?
【发布时间】:2022-02-01 06:41:04
【问题描述】:

如何通过 Postman 为我的 mongoDB 中的每个条目生成唯一 ID?

我使用http://localhost:8000/api/user/store 运行邮递员 POST 并发送

{
"name":"testname",
"email":"testemail@test.com",
"phone":"testnumber",
"city":"testcity",
}

这会保存在我的 mongoDB 中并在我的 mongoDB 指南针中显示

_id:61f7e48f0c651345677b7775
name:"testname"
email:"testemail@test.com"
phone:"testnumber"
city:"testcity"
__v:0

如何生成唯一 ID 并将其添加到此过程之间,以便将其保存如下:

_id:61f7e48f0c651345677b7775
uniqueID:68465135
name:"testname"
email:"testemail@test.com"
phone:"testnumber"
city:"testcity"
__v:0

我的模型 userData.js 看起来像这样:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    phone: {
        type: String,
        required: true
    },
    city: {
        type: String,
        required: true
    },
}, { timeStamps: true })

const User = mongoose.model('User', userSchema);
//export model to use in other files
module.exports = User;

这是来自UserController.js 的关于如何保存数据的 sn-p

// Saves user to the database
const store = (req, res, next) => {
    let user = new User({
        name: req.body.name,
        email: req.body.email,
        phone: req.body.phone,
        city: req.body.city,
    })
    user.save()
        .then(response => {
            res.json({
                message: 'User added successfully!'
            })
        })
        .catch(error => {
            res.json({
                message: 'An error occured!'
            })
        })
}

uniqueID 可以是我刚刚添加的任何数字作为示例。但它必须是独一无二的。我怎样才能做到这一点?任何建议都会有所帮助。

【问题讨论】:

  • 你能分享你的模型吗?
  • _id 是独一无二的不是吗?
  • @LucjanGrzesik 编辑添加模型

标签: javascript node.js json mongodb


【解决方案1】:

据我所知,_id (ObjectId) 已经是唯一的了,如果你想提供自己的_id,你只需要在实体中设置即可。

【讨论】:

    【解决方案2】:

    您可以使用 MongoDB 中的 _id,因为如果您不喜欢 MongoDB _id 的格式,它始终是唯一的,您可以将其更改为 nanoid。


    型号

    带有新的uniqueId 字段

    import { nanoid } from 'nanoid';
    
    const UserSchema = new mongoose.Schema({
      name: string,
      uniqueId: {
        type: String,
        required: true,
        default: () => nanoid(7),
        index: { unique: true },
      },
      email: String,
      phone: String,
      city: String,
    })
    
    

    您也可以使用 nanoid 覆盖 _id,这样它就不会在您的架构中创建额外的字段

    import { nanoid } from 'nanoid';
    
    const UserSchema = new mongoose.Schema({
      _id: {
        type: String,
        default: () => nanoid(),
      },
      name: string,
      email: String,
      phone: String,
      city: String,
    })
    

    控制器

    // Saves user to the database
    const store = async (req, res, next) => {
      const { name, email, phone, city} = req.body;
      try {
        let user = new User({
          name,
          email,
          phone,
          city,
        });
        const savedUser = await user.save();
        return res.json({
          message: 'User added successfully!',
        });
      } catch (error) {
        console.log(error)
        return res.json({
          message: 'An error occured!',
        });
      }
    };
    
    

    【讨论】:

    • 字段上的唯一索引会更好,因为它既允许通过自定义 ID 进行查询,又可以防止数据库级别的重复。
    • 是的,你是对的,改变了我的答案
    • 有了索引,就不用去检查用户是否存在了。 save 调用也会引发错误,无需额外查询。
    • 这仅适用于第一个,下一个条目仍然具有先前生成的 ID 本身。难道我做错了什么? (控制器中的savedUser 已声明但未使用)
    • 你知道@Parzival 了吗?
    【解决方案3】:

    从技术上讲,您无法生成唯一的 id,但它必须足够大才能不生成相同的 id,例如:

    function create_UUID(){
        var dt = new Date().getTime();
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = (dt + Math.random()*16)%16 | 0;
            dt = Math.floor(dt/16);
            return (c=='x' ? r :(r&0x3|0x8)).toString(16);
        });
        return uuid;
    }
    

    输出:

    1fe35579-5ce7-46ec-89e0-7e7236700297
    

    来源:

    https://www.w3resource.com/javascript-exercises/javascript-math-exercise-23.php

    【讨论】:

      【解决方案4】:

      mongodb javascript 驱动已经有UUID:

      db.foo.insert( {x: new UUID()} );
      db.foo.aggregate([ {$project: {x:true, x_type: {$type: "$x"}}} ]);
      {
          "_id" : ObjectId("61f81af6a565bb368b38e345"),
          "x" : UUID("b639a8b5-2598-429f-92e0-630c6b5bfbdc"),
          "x_type" : "binData"
      }
      

      如果您不喜欢实际的UUID 对象,请捕获其字符串代表。请注意,不幸的是,对象上的toString() 不会产生892ab869-3339-41b3-a612-5c29871f4e57,而是整个UUID("892ab869-3339-41b3-a612-5c29871f4e57"),所以你必须substr 它:

      db.foo.insert( {x: (new UUID()).toString().substr(6,36) });
      db.foo.aggregate([ {$project: {x:true, x_type: {$type: "$x"}}} ]);
      {
          "_id" : ObjectId("61f81b56a565bb368b38e348"),
          "x" : "d5af9fb4-768c-4e17-b69a-8bcd80f8bf1e",
          "x_type" : "string"
      }
      

      或者,为简单起见,您可以使用hex() 方法:

      db.foo.insert( {x: (new UUID()).hex() } );
      db.foo.aggregate([ {$project: {x:true, x_type: {$type: "$x"}}} ]);
      {
          "_id" : ObjectId("61f81ba9a565bb368b38e34e"),
          "x" : "b9810abea4344932b3da15f7f0d58e2c", // note the dashes went away
          "x_type" : "string"
      }
      

      在所有情况下,驱动程序(不是服务器)将创建一个唯一的_id(如果未提供)。在集成和移动数据时,创建一个不与数据库绑定的唯一 ID(例如 _id)可能很有价值(与将 ROWID 从 CSV 中的 Oracle 移出相比;不是很有用)。注意:_id 的默认生成类型是 ObjectId,它是 BSON 中的一种类型,不一定与 MongoDB 绑定。也就是说,UUID 更像是一个“机器/数据库密钥”,而不是一个熟悉的可以唯一的业务密钥。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多