Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

2013-4-14

  • Loading branch information...
commit ec4d461e34e1c69fecb600c744de006015b483e2 1 parent 2dee7fb
@mariodu authored
View
71 README.md
@@ -1,4 +1,71 @@
mongoose-id-autoinc
-===================
+====================
-mongoose-id-autoinc
+mongoose的一个plugin,用来解决使用mongoose时mongodb的_id自增问题,摆脱一堆对人类不友好的_id字段。
+自增字段名可以自定义。
+
+## 依赖
+
+- [Node.js](http://nodejs.org/)
+- [MongoDB](http://www.mongodb.org)
+- [Mongoose](http://mongoosejs.com)
+
+##原理参照
+
+MongoDB的官方文档
+
+[Create an Auto-Incrementing Sequence Field](http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/)
+
+采用的是方法一,在数据库中新建了一个counter计数的collection,记录每个model的大id,然后在save时赋值。
+使用findAndModify实现递增,由于$inc是原子操作,所以不用担心并发。
+
+## 安装
+
+通过npm
+
+ npm install mongoose-id-autoinc
+
+## 选项
+
+- `model` - Mongoose model的名字,必须的选项
+- `field` - 自增字段的名,默认为_id
+- `start` - 自增的初始值,默认1
+- `step` - 自增的步长,默认1
+
+
+## 使用
+
+例子代码:
+
+ $ node examples/example.js
+
+1.在项目里require mongoose以及插件
+
+ var mongoose = require('mongoose'),
+ Schema = mongoose.Schema,
+ db = mongoose.createConnection('127.0.0.1', 'yourDatabaseName'),
+ autoinc = require('mongoose-id-autoinc');
+
+2.初始化插件,然后定义你自己的表结构,在和插件关联上
+
+ autoinc.init(db);
+ //可以指定counter名称,init(db,countername)
+
+ var UserSchema = new Schema({
+ name: String,
+ email: String
+ });
+
+ UserSchema.plugin(autoinc.plugin, { model: 'User' });
+
+3.然后就可以创建自己的model,它的_id就会自增(1,2,3...)
+
+ var User = db.model('User', UserSchema);
+
+4.可选字段
+
+ UserSchema.plugin(autoinc.plugin, { model: 'User',field: 'seqnumber', start: 100, step: 10 });
+
+---------------------------------------
+
+#### ©MarioDu 2013-4-14
View
51 examples/example.js
@@ -0,0 +1,51 @@
+/**
+ * @author MarioDu <dujiakun@gmail.com>
+ */
+
+var dbName = 'id_autoinc_example',
+ mongoose = require('mongoose'),
+ Schema = mongoose.Schema,
+ db = mongoose.createConnection('127.0.0.1', dbName),
+ autoinc = require('../index');
+
+autoinc.init(db);
+
+var UserSchema = new Schema({
+ name: String,
+ email: String
+});
+
+UserSchema.plugin(autoinc.plugin, {
+ model: 'User',
+ field: 'seqnumber',
+ start: 100,
+ step: 10
+});
+
+var User = db.model('User', UserSchema);
+
+console.log('Database: ' + dbName);
+console.log('Collection: ' + User.collection.name);
+
+var user_1 = new User({
+ name: 'LiuBei',
+ email: 'liubei@xishu.com'
+});
+
+user_1.save(function (err, res) {
+
+ console.log('New record added:');
+ console.log(res);
+});
+
+var user_2 = new User({
+ name: 'ZhouYu',
+ email: 'zhouyu@wu.com'
+});
+
+user_2.save(function (err, res) {
+
+ console.log('New record added:');
+ console.log(res);
+ mongoose.disconnect();
+});
View
5 index.js
@@ -0,0 +1,5 @@
+/**
+ * @author MarioDu <dujiakun@gmail.com>
+ */
+
+module.exports = require('./lib/mongooes-id-autoinc.js');
View
105 lib/mongooes-id-autoinc.js
@@ -0,0 +1,105 @@
+/**
+ * @author MarioDu <dujiakun@gmail.com>
+ */
+
+module.exports = new (function () {
+
+ var db, Counter, mongoose, counterName;
+
+ this.plugin = function(schema, options) {
+
+ if (!options.model)
+ throw new Error('Missing required parameter: model');
+
+ options.model = options.model.toLowerCase() + '_id';
+ options.field = options.field || '_id';
+ options.start = (!isNaN(options.start)) ? options.start : 1;
+ options.step = (!isNaN(options.step)) ? options.step : 1;
+
+ var fields = {},
+ ready = false;
+
+ // Adding new field into schema
+ fields[options.field] = {
+ type: Number,
+ unique: true,
+ require: true
+ };
+ schema.add(fields);
+
+ // Initializing of plugin
+ Counter.findOne({
+ model: options.model,
+ field: options.field
+ }, function (err, res) {
+ if (!res)
+ (new Counter({
+ model: options.model,
+ field: options.field,
+ seq: options.start
+ })).save(function () {
+ ready = true;
+ });
+ else
+ ready = true;
+ });
+
+ schema.pre('save', function (next) {
+
+ var doc = this;
+
+ // Increment method refer to http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/,
+ // first method
+ function save () {
+
+ if (ready)
+ Counter.collection.findAndModify({
+ model: options.model,
+ field: options.field
+ }, [], {
+ $inc: {
+ seq: options.step
+ }
+ }, {
+ 'new': true,
+ upsert: true
+ }, function (err, res) {
+
+ if (!err)
+ doc[options.field] = res.seq - 1;
+ next(err);
+ });
+ else
+ setTimeout(save, 5);
+ // Delay before plugin will be sucessfully initialized
+ }
+ save();
+ });
+ };
+
+ this.init = function (database, counter) {
+
+ db = database;
+ mongoose = require('mongoose');
+ counterName = counter || 'counter';
+
+ var schema = new mongoose.Schema({
+ model: {
+ type: String,
+ require: true
+ },
+ field: {
+ type: String,
+ require: true
+ },
+ seq: {
+ type: Number,
+ default: 1
+ }
+ });
+ schema.index({ field: 1, model: 1 }, { unique: true, required: true, index: -1 });
+
+ Counter = db.model(counterName, schema);
+ };
+
+})();
View
38 package.json
@@ -0,0 +1,38 @@
+{
+ "name": "mongoose-id-autoinc",
+ "description": "Creating of auto increment id fields",
+ "version": "2013.4.14-1",
+ "author": "MarioDu",
+ "dependencies": {
+ "mongoose": ">=3.0.0"
+ },
+ "devDependencies": {
+ "mongoose": ">=3.0.0"
+ },
+ "keywords": [
+ "mongoose",
+ "mongo",
+ "mongodb",
+ "auto-increment",
+ "increment",
+ "field",
+ "_id",
+ "id"
+ ],
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/mariodu/mongoose-id-autoinc.git"
+ },
+ "main": "./index.js",
+ "readmeFilename": "README.md",
+ "directories": {
+ "example": "examples"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified,you can run 'node examples/example.js'\" && exit 1"
+ },
+ "license": "BSD"
+}
Please sign in to comment.
Something went wrong with that request. Please try again.