前言
因为想实现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
});
}
})
})
自动更新序号无压力!!!
总结
里面的异步处理,由于目前理解不够透彻,只能写个简单的异步,有细节处理的不好。等深入学习后,再重新改写。