HMR*_*HMR 19 javascript auto-increment mongoose mongodb
根据这篇mongodb文章,可以自动增加一个字段,我想使用计数器收集方式.
这个例子的问题是我没有成千上万的人使用mongo控制台在数据库中键入数据.相反,我试图使用猫鼬.
所以我的架构看起来像这样:
var entitySchema = mongoose.Schema({
testvalue:{type:String,default:function getNextSequence() {
console.log('what is this:',mongoose);//this is mongoose
var ret = db.counters.findAndModify({
query: { _id:'entityId' },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
}
});
Run Code Online (Sandbox Code Playgroud)
我在同一个数据库中创建了计数器集合,并添加了一个_id为'entityId'的页面.从这里我不知道如何使用mongoose更新该页面并获得递增的数字.
计数器没有架构,我希望它保持这种方式,因为这实际上不是应用程序使用的实体.它只应在模式中用于自动增量字段.
edt*_*ech 39
以下是如何在Mongoose中实现自动增量字段的示例:
var CounterSchema = Schema({
_id: {type: String, required: true},
seq: { type: Number, default: 0 }
});
var counter = mongoose.model('counter', CounterSchema);
var entitySchema = mongoose.Schema({
testvalue: {type: String}
});
entitySchema.pre('save', function(next) {
var doc = this;
counter.findByIdAndUpdate({_id: 'entityId'}, {$inc: { seq: 1} }, function(error, counter) {
if(error)
return next(error);
doc.testvalue = counter.seq;
next();
});
});
Run Code Online (Sandbox Code Playgroud)
moo*_*ara 29
你可以使用mongoose-auto-increment
如下包:
var mongoose = require('mongoose');
var autoIncrement = require('mongoose-auto-increment');
/* connect to your database here */
/* define your CounterSchema here */
autoIncrement.initialize(mongoose.connection);
CounterSchema.plugin(autoIncrement.plugin, 'Counter');
var Counter = mongoose.model('Counter', CounterSchema);
Run Code Online (Sandbox Code Playgroud)
你只需要初始化autoIncrement
一次.
小智 12
投票最多的答案不起作用.这是修复:
var CounterSchema = new mongoose.Schema({
_id: {type: String, required: true},
seq: { type: Number, default: 0 }
});
var counter = mongoose.model('counter', CounterSchema);
var entitySchema = mongoose.Schema({
sort: {type: String}
});
entitySchema.pre('save', function(next) {
var doc = this;
counter.findByIdAndUpdateAsync({_id: 'entityId'}, {$inc: { seq: 1} }, {new: true, upsert: true}).then(function(count) {
console.log("...count: "+JSON.stringify(count));
doc.sort = count.seq;
next();
})
.catch(function(error) {
console.error("counter error-> : "+error);
throw error;
});
});
Run Code Online (Sandbox Code Playgroud)
该选项的参数为您提供了更新的结果,如果它不存在,它会创建一个新文档.你可以在这里查看官方文档.
如果您需要排序索引,请检查此文档
我结合了答案中所有(主观和客观)好的部分,并提出了以下代码:
const counterSchema = new mongoose.Schema({
_id: {
type: String,
required: true,
},
seq: {
type: Number,
default: 0,
},
});
// Add a static "increment" method to the Model
// It will recieve the collection name for which to increment and return the counter value
counterSchema.static('increment', async function(counterName) {
const count = await this.findByIdAndUpdate(
counterName,
{$inc: {seq: 1}},
// new: return the new value
// upsert: create document if it doesn't exist
{new: true, upsert: true}
);
return count.seq;
});
const CounterModel = mongoose.model('Counter', counterSchema);
entitySchema.pre('save', async function() {
// Don't increment if this is NOT a newly created document
if(!this.isNew) return;
const testvalue = await CounterModel.increment('entity');
this.testvalue = testvalue;
});
Run Code Online (Sandbox Code Playgroud)
这种方法的好处之一是所有与计数器相关的逻辑都是独立的。您可以将其存储在单独的文件中,并将其用于导入CounterModel
.
如果要增加该_id
字段,则应在架构中添加其定义:
const entitySchema = new mongoose.Schema({
_id: {
type: Number,
alias: 'id',
required: true,
},
<...>
});
Run Code Online (Sandbox Code Playgroud)
我知道这已有很多答案,但我会分享我的解决方案,这是IMO的简短易懂:
// Use pre middleware
entitySchema.pre('save', function (next) {
// Only increment when the document is new
if (this.isNew) {
entityModel.count().then(res => {
this._id = res; // Increment count
next();
});
} else {
next();
}
});
Run Code Online (Sandbox Code Playgroud)
确保entitySchema._id
有type:Number
.猫鼬版:5.0.1
.
因此,结合多个答案,这就是我最终使用的内容:
counterModel.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const counterSchema = new Schema(
{
_id: {type: String, required: true},
seq: { type: Number, default: 0 }
}
);
counterSchema.index({ _id: 1, seq: 1 }, { unique: true })
const counterModel = mongoose.model('counter', counterSchema);
const autoIncrementModelID = function (modelName, doc, next) {
counterModel.findByIdAndUpdate( // ** Method call begins **
modelName, // The ID to find for in counters model
{ $inc: { seq: 1 } }, // The update
{ new: true, upsert: true }, // The options
function(error, counter) { // The callback
if(error) return next(error);
doc.id = counter.seq;
next();
}
); // ** Method call ends **
}
module.exports = autoIncrementModelID;
Run Code Online (Sandbox Code Playgroud)
myModel.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const autoIncrementModelID = require('./counterModel');
const myModel = new Schema({
id: { type: Number, unique: true, min: 1 },
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date },
someOtherField: { type: String }
});
myModel.pre('save', function (next) {
if (!this.isNew) {
next();
return;
}
autoIncrementModelID('activities', this, next);
});
module.exports = mongoose.model('myModel', myModel);
Run Code Online (Sandbox Code Playgroud)
这个问题已经足够复杂,并且有足够多的陷阱,最好依赖经过测试的猫鼬插件。
在http://plugins.mongoosejs.io/上的大量“自动增量”插件中,维护和记录得最好的(而不是分叉)是mongoose sequence。
归档时间: |
|
查看次数: |
57058 次 |
最近记录: |