mongodb之利用findAndModify()和nodejs實現自定義自增id


mongodb有自己的ObjectId,為什么我們還要用自己的id呢?因為自定義的id可以實現自己的業務需求,比如我有一條記錄,我需要更新它的一個字段,而且更新之后的數據要排在最前面。但是這個時候objectId是不變的,即使是使用毫秒級的時間戳,也可能同時插入多條數據,讓你不知道更新的先后順序。這個時候,你就需要自定義自增長的id.

項目使用的是nodejs,nodejs的io操作基本是異步的,邏輯運算等操作是同步的,所以我思考了大概兩種實現自增長的方式,一種是設一個全局的id,只要有更新操作,就先將這個id先增加,再寫入,如果有重啟,初始化的時候就先從數據庫把這個最大的id讀出來,再作為重啟后更新的id使用;第二種就是用findAndModify()的方式實現。

我使用的是第二種,主要利用了findAndModify()查找和更新是原子操作的特點。

storage部分代碼:

'use strict';
var _ = require('lodash');

var mongodb = require('mongodb');


var Storage = function(){
	this.db = {};
}

Storage.prototype.connect = function(opts,cb){
	var self = this;
	var client = mongodb.MongoClient;
	client.connect(opts.uri,function(err,db){
		if(err){
			return cb(err);
		}
		self.db = db;
		return cb();
	})
}

Storage.prototype.updateNewIncoming = function(tx,cb){
	var self = this;

		 self.db.collection('counters').findAndModify( 
			{_id:'txid'},	
			[['_id','asc']],
			{$inc:{seq:1}},	
			{new:true},function(err,result){
			if(err){
				console.log(err);
				return cb(err);
			}
		
			console.log('result111'+JSON.stringify(result.value.seq));
			self.db.collection('tx_income').update({
				txid:tx.id,
				type:'newIncome',
			},{
				txid:tx.id,
				type:'newIncome',
				tx:tx,
				id:result.value.seq
			},{
				w:1,
				upsert:true,
			},cb)
		});
}

業務部分代碼:

var Storage = require('./storage');
var config = require('./config');
var async = require('async');

var storage = new Storage();

var opts = {
    uri : config.mongodb.uri  // 自己設置config
};

async.series([
    function(next){
        storage.connect(opts,next);
    },
        function(next){
        storage.updateNewIncoming(tx,function(){ // tx自己設置
            console.log('next2');
            return next();
        })
    },    
],function(err){
// TODO(): 業務代碼自己去寫            
});

大家要注意的地方在findAndModify()里邊,可能寫法不一樣,這個跟nodejs的驅動有關,我在命令行里邊用這種方式:

db.counters.findAndModify({query:{'_id':'txid'},update:{$inc:{'seq':1}},new:true})

可以實現操作,但是在代碼中不行,所以大家可以去試一下。

參考 https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/#db.collection.findAndModify

 

送你幾顆比特幣玩玩:

https://www.coincola.app/acts/red-packet?type=invitation&packet_id=gBbVudr7GwuTF3r71ihUq8vDiuiNdAgL&lang=zh-CN

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM