如何使用我的mongoose集合插入自动增量数字

时间:2016-01-14 09:45:05

标签: node.js mongodb mongoose

我是mongoose的新手,我有一个像这样的猫鼬模式:

var user = mongoose.Schema({
    userID: {
        type: String,
        required:true
    },
    seq: {
        type: Number,
        default: 0
    },
    firstname: {
        type: String
    },
    lastname: {
        type: String
    },
    dob: {
        type: String
    },
    email: {
        type: String,
        required: true
    },
    username: {
        type: String,
        required: true
    },
    displayname: {
        type: String
    },
    password: {
        type: String,
        required: true
    },
    mobile: {
        type: String
    },
    profilePic: {
        type: String
    },
    city: {
        type: String
    },
    gender: {
        type: String
    },
    profileType: {
        type: String,
        required: true
    },
    profileId: {
        type: String
    },
    isActive: {
        type: Number
    },
    ageVerified: {
        type: String
    },
    ipAddress: {
        type: String
    },
    key: {
        type: String
    },
    osType: {
        type: String
    },
    osVersion: {
        type: String
    },
    deviceName: {
        type: String
    },
    joinedDate: {
        type: String
    },
    connectedAccounts: [{
        profileType: {
            type: String
        },
        profileId: {
            type: String
        },
        email: {
            type: String
        }
    }]
}, {collection: 'user'});

请注意,userID是一个自动增量编号字段,用于使用mongoose查询插入值am:

new user(contents).save(function (err,doc){};

'contents'是一个对象,它包含除userID之外的所有字段的数据,这里我的问题是如何在插入其他字段的记录时为userID(自动增量号)插入值?我引用这个link来设置自动增量值...但我不知道如何在猫鼬中使用它?

3 个答案:

答案 0 :(得分:4)

在MongoDB教程 Create an Auto-Incrementing Sequence Field 之后,您需要先创建一个单独的counters集合来跟踪最后使用的数字序列。 _id字段包含序列名称,即用户集合中的userID字段,seq字段包含序列的最后一个值。

首先,在计数器集合中插入userID的初始值:

db.counter.insert(
   {
      "_id": "userID",
      "seq": 0
   }
)

填充了计数器集合后,在Mongoose中生成其架构:

var counterSchema = mongoose.Schema({
    "_id": { "type": String, "required": true },
    "seq": { "type": Number, "default": 0 }
});

var counter = mongoose.model('counter', counterSchema);

然后重新定义您的用户架构,以便在保存用户模型时,它首先调用计数器模型的findByIdAndUpdate()方法以原子方式递增seq值并返回此新值,然后可将其用作下一个userID值:

var userSchema = mongoose.Schema({
    "userID": { "type": String, "required": true },
    "firstname": { "type": String },
    "lastname": { "type": String },
    // other properties ...
    }, { "collection": "user" }
);

userSchema.pre("save", function (next) {
    var doc = this;
    counter.findByIdAndUpdate(
        { "_id": "userID" }, 
        { "$inc": { "seq": 1 } }
    , function(error, counter)   {
        if(error) return next(error);
        doc.userID = counter.seq.toString();
        next();
    });
});

答案 1 :(得分:1)

考虑到schema.findByIdAndUpdate的逻辑是"返回当前值,然后递增它",您还可以使用@ chridam'解决方案进行以下编辑:

var counter = mongoose.model('counter', counterSchema);


userSchema.pre("save", function (next) {
  var doc = this;
  counter.findByIdAndUpdate(
      { "_id": "userID" }, 
      { "$inc": { "seq": 1 } }
  , function(error, c /*counter*/)   {
      if(error)
        return next(error);
      else if(!c) {
        c = new counter({ _id: "userID" }, { $inc: { seq: 1 } };
        c.save(function() {
          doc.userID = (c.seq - 1) + '';
          next();
        });
      } else {
        doc.userID = counter.seq.toString();
        next();
      }
  });
});

请注意,此解决方案可让您的代码从头开始运行,而不会强制您初始化数据库。

技巧在于循环的第一轮。 counter未定义,因此您需要对其进行初始化,但如果将其初始化为0,则下一次勾选代码会再次尝试分配userID=0

这是因为一方面有schema.findByIdAndUpdate的逻辑首先读取值然后递增它,另一方面你需要一个逻辑来指定 - 尽管这个值。

您可以通过使算法跳过第一步并设置上述变量值来加入这两个逻辑。

注意:counterSchema与chridam的相同:

counterSchema = mongoose.Schema({
  "_id": { "type": String, "required": true },
  "seq": { "type": Number, "default": 0 }
});

答案 2 :(得分:1)

如果您要根据集合的长度自动增加道具,可以执行以下操作:

UserSchema.pre("save", function (next) {
  if (this.isNew) {
    this.constructor.find({}).then((users) => {
      this.autoIncrementProp = users.length + 1;
      next();
    });
  }
});

isNew 是保留的架构名称(布尔标记,用于指定文档是否是新的。