猫鼬中的自动增量ID

时间:2015-09-20 23:09:29

标签: mongodb mongoose mongodb-query

如何在猫鼬中使用自动增量id?我希望我的id能够像1,2,3,4那样开始,而不是mongodb为你创造的奇怪的id号码?

这是我的架构:

var PortfolioSchema = mongoose.Schema({
    url: String,
    createTime: { type: Date, default: Date.now },
    updateTime: { type: Date, default: Date.now },
    user: {type: Schema.Types.ObjectId, ref: 'User'}
});

2 个答案:

答案 0 :(得分:4)

使用mongoose-auto-increment: https://github.com/codetunnel/mongoose-auto-increment

var mongoose = require('mongoose');
var autoIncrement = require('mongoose-auto-increment');
var connection = ....;
autoIncrement.initialize(connection);

var PortfolioSchema = new mongoose.Schema({
    url: String,
    createTime: { type: Date, default: Date.now },
    updateTime: { type: Date, default: Date.now },
    user: {type: Schema.Types.ObjectId, ref: 'User'}
});

//Auto-increment
PortfolioSchema.plugin(autoIncrement.plugin, { model: 'Portfolio' });

module.exports = mongoose.model('Portfolio', PortfolioSchema);

或者如果您更喜欢使用其他字段而不是覆盖_id,只需添加字段并在自动增量初始化中将其列出:

var PortfolioSchema = new mongoose.Schema({
    portfolioId: {type: Number, required: true},
    url: String,
    createTime: { type: Date, default: Date.now },
    updateTime: { type: Date, default: Date.now },
    user: {type: Schema.Types.ObjectId, ref: 'User'}
});

//Auto-increment
PortfolioSchema.plugin(autoIncrement.plugin, { model: 'Portfolio', field: 'portfolioId' });

答案 1 :(得分:1)

如果你想在_id中有一个递增的数值,那么基本的过程是你需要一些东西从某个商店的某个地方返回那个值。一种方法是使用MongoDB本身来存储保存每个集合的_id值的计数器的数据,这在Create and Auto-Incrementing Sequence Field下的手册中有所描述。

然后在创建每个新项目时,使用已实现的函数获取“计数器”值,并将其用作文档中的_id

当覆盖此处的默认行为时,mongoose要求您同时指定_id并使用_id: Number明确指定类型,并且您要求它不再自动尝试提供ObjectId 1}}键入{ "_id": false }作为架构的选项。

以下是实践中的一个实例:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');

var counterSchema = new Schema({
  "_id": String,
  "counter": { "type": Number, "default": 1 }
},{ "_id": false });

counterSchema.statics.getNewId = function(key,callback) {
  return this.findByIdAndUpdate(key,
    { "$inc": { "counter": 1 } },
    { "upsert": true, "new": true },
    callback
  );
};

var sampleSchema = new Schema({
  "_id": Number,
  "name": String
},{ "_id": false });

var Counter = mongoose.model( 'Counter', counterSchema ),
    ModelA = mongoose.model( 'ModelA', sampleSchema ),
    ModelB = mongoose.model( 'ModelB', sampleSchema );


async.series(
  [
    function(callback) {
      async.each([Counter,ModelA,ModelB],function(model,callback) {
        model.remove({},callback);
      },callback);
    },
    function(callback) {
      async.eachSeries(
        [
          { "model": "ModelA", "name": "bill" },
          { "model": "ModelB", "name": "apple" },
          { "model": "ModelA", "name": "ted" },
          { "model": "ModelB", "name": "oranage" }
        ],
        function(item,callback) {
          async.waterfall(
            [
              function(callback) {
                Counter.getNewId(item.model,callback);
              },
              function(counter,callback) {
                mongoose.model(item.model).findByIdAndUpdate(
                  counter.counter,
                  { "$set": { "name": item.name } },
                  { "upsert": true, "new": true },
                  function(err,doc) {
                    console.log(doc);
                    callback(err);
                  }
                );
              }
            ],
            callback
          );
        },
        callback
      );
    },
    function(callback) {
      Counter.find().exec(function(err,result) {
        console.log(result);
        callback(err);
      });
    }
  ],
  function(err) {
    if (err) throw err;
    mongoose.disconnect();
  }
);

为了方便起见,这在模型上实现了一个静态方法.getNewId(),它只是描述性地包装了.findByIdAndUpdate()中使用的主函数。这是手册页部分中提到的.findAndModify()形式。

这样做的目的是它将在Counter模型集合中查找特定的“key”(实际上再次是_id)并执行操作以“递增”该键的计数器值并返回修改后的文档。这也是“upsert”选项的辅助,因为如果所请求的“key”还没有文档,那么它将被创建,否则该值将通过$inc递增,并且它始终是默认值将是1。

此处的示例显示两个计数器是独立维护的:

{ _id: 1, name: 'bill', __v: 0 }
{ _id: 1, name: 'apple', __v: 0 }
{ _id: 2, name: 'ted', __v: 0 }
{ _id: 2, name: 'oranage', __v: 0 }
[ { _id: 'ModelA', __v: 0, counter: 2 },
  { _id: 'ModelB', __v: 0, counter: 2 } ]

首先在创建每个文档时列出它们,然后显示“计数器”集合的结束状态,该集合保存所请求的每个密钥的最后使用值。

另请注意,那些“怪异数字”的特定目的是始终保证其独特性,并且始终按顺序增加。请注意,他们这样做,无需再次访问数据库,以便安全地存储和使用递增的数字。所以这应该值得考虑。