前言

因为想实现id的自增,但又不同于SQL,有自增功能,看了菜鸟教程,提供了一种直接操作数据库的方法,但是无法实际运用到js中。我就摸索通过js的方式实现自增id。想了两种方法,第一种是异步实现的,但里面有点bug,一直没解决。所以更偏向于第二种方法。

MongoDB 自动增长
MongoDB 没有像 SQL 一样有自动增长的功能, MongoDB 的 _id 是系统自动生成的12字节唯一标识。但在某些情况下,我们可能需要实现 ObjectId 自动增长功能。由于 MongoDB 没有实现这个功能,我们可以通过编程的方式来实现,以下我们将在 counters 集合中实现_id字段自动增长。


以下是实现方法

一、结合异步,使用js方法

(一)、定义一个模型

其结构表一定要含有sequence_value(自己定义,默认初始值是0),和id(初始值:0)。
在这里插入图片描述
在数据库中添加上这个初始数据。
在这里插入图片描述

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

(二)、使用findOneAndUpdate

1.定义一个异步函数

因为mongoose从数据库获取数据的操作是异步的,我们要在它获取过数据之后再进行赋值,所以使用then,得到返回回来的值。

/**
 * 
 * @param {*} sequenceName: findOneAndUpdate函数的conditions
 * @returns 返回新的sequence_value值,用于重新赋值id
 */
async function getNextSequenceValue(sequenceName) {
    let sequenceDocument  = await HomeList.findOneAndUpdate(
            {id: sequenceName },
            { $inc:{sequence_value:0.5} },
            {new:true},function(err, data) {
                if(err) {
                    console.log('数据库发生错误')
                }
                else if(!data) {
                    console.log('未查找到相关数据')
                    console.log(data)
                    
                }
                else if(data){
                    console.log('修改数据成功')
                    console.log(data)
                }
            }
        )
    return sequenceDocument.sequence_value;
 }

2.在路由中进行存储

    getNextSequenceValue(0).then((data) => {
        console.log('当前的'+data);
        var user = new HomeList({
        id: data,  
        title,      
        desc,      
        imgUrl,
      });
            user.save((err, docs) => {
        if(err) {
            res.send({
                status: 'error',
                statusCode: res.statusCode,
                msg: '保存失败'+err,
            });
        } else {
          res.send({
            status : "success",
            data: docs
          });
        }
      })
    })

然后去测试就可以正确自增了。
在这里插入图片描述


二、全局变量,记录编号

整体思路如下:首先定义一个全局的变量,用于更新每次的序号。每次在路由发出之前, 先取出最新的序号,对 SERIALCODE 进行重新赋值

let SERIALCODE = {"A":1001,"B":10001,"C":100001,"D":1000001,"E":10000001} 
// 用于更新序列
exports.genSerialCode = (serial) => {
    return ((SERIALCODE[serial]++)+1);
}

// 初始化序列变量
exports.getSerialNum = (serialCode) => {
  Article.count({},function(err, total){
  	// 每次先取出最新的序号,对 SERIALCODE 进行重新赋值 
    Article.find({},{"articleSerial": 1},{skip:total - 1},function(err, data){
        console.log(data[0].articleSerial);
        if(data==undefined)
            return data=[]
        serialCode["A"] = parseInt(data[0].articleSerial)|| SERIALCODE["A"];
        console.log(SERIALCODE['A']);

      })
  });
}

exports.SERIALCODE = SERIALCODE;

在article.js中进行引入

const serial = require('./common/serial')
serial.getSerialNum(serial.SERIALCODE);

router.post('/addArticle' , (req, res) => {
    const {articleName, author, content} = req.body;
    // console.log(serial.genSerialCode("A"));
    var user = new Article({
        id:1,
        articleName, // 用户名
        author, // 用户密码
        content, // 用户年龄
        releaseDate: getNowTime(), // 最近登录一次时间
        articleSerial: serial.genSerialCode("A"),	// 获取最新的序号
    });
    user.save( (err, docs) => {
        if(err) {
            res.send({
                status: 'error',
                statusCode: codeMessage[res.statusCode],
                msg: '保存失败',
            });
        } else {
          res.send({
            status : "success",
            statusCode: codeMessage[res.statusCode],
            data: docs
          });
        }
      }) 
})

自动更新序号无压力!!!
在这里插入图片描述

总结

里面的异步处理,由于目前理解不够透彻,只能写个简单的异步,有细节处理的不好。等深入学习后,再重新改写。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐