[英]Increment a number field with Mongoose? For sorting results on .find
我有一个看起来像这样的猫鼬模型:
module.exports = mongoose.model('Item', {
text : String,
position: Number
});
我正在寻找一个位置字段,该字段在所有文档的.length之类的地方递增,以便对All .find的结果进行排序:
// get All Items
app.get('/itemsList', function(req, res) {
// use mongoose to get all items in the database
Item.find({
sort : { position: 1 } // sort by Ascending Position
}. function(err, items) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
res.send(err)
res.json(items); // return all items in JSON format
});
});
有没有一种方法可以使用node.js中的一些JavaScript自动为Position字段填充数字?
// create an item
app.post('/api/item', function(req, res) {
// create an item, information comes from AJAX request from Angular
Item.create({
text : req.body.text,
position:
// something using ++items.length
}, function(err, item) {
if (err)
res.send(err);
});
});
Mongoose使您可以进入save
, validate
和remove
方法,并在执行之前和之后执行代码。
该代码可以是异步的。 例如,您可能会这样做:
var schema = mongoose.Schema({
text : String,
position: Number
});
schema.pre("validate", function(next) {
var doc = this;
// If 'position' is not filled in, fill it in.
// Not using !position because 0 might be a valid value.
if(typeof position !== "number") {
// Count the number of Items *
mongoose.model("Item").count(function(err, num) {
// If there was an error, pass it to next().
if(err)
return next(err);
// Update the position, then call next();
doc.position = num;
return next();
});
} else {
// There is no need to count, so call next().
next();
}
});
module.exports = mongoose.model('Item', schema);
这里更多 。
在验证开始之前,将对项目数进行计数。 然后,设置位置。
在上述代码准备就绪之前,验证和其他预验证器**挂钩将不会开始。
*我在这里使用mongoose.model来获取模型,因为该模型尚未编译(在下面发生)。
**文档向您展示了如何使多个预验证器挂钩并行执行。 在本示例中,我选择不执行此操作,因为代码更易于阅读,并且因为您可能实际上需要验证程序才能按顺序运行。
在预验证挂钩中,您可以在其他情况下放置一些逻辑。 当插入具有现有position
值的Item
时,您需要向下移动每条记录。 您可以通过执行以下操作来做到这一点:
this.isModified("position")
检查自上次保存以来该值是否已更改。 您可能还需要doc.isNew()。 position
的现有文档。 类似于Item.where({_id: {$ne: this._id}, position: this.position}).count()
Item.update({position: {$gte: this.position}}, {position: {$inc: 1}}, {multi: 1})
以上应该可以。 但是,当您删除文档时,它将留下空白。
另外,查看索引。 您需要在位置字段中添加一个。 也许甚至是unique index
。
根据@RikkusRukkus向下移动记录的步骤,这是else情况(待测试)的逻辑
// load mongoose since we need it to define a schema and model
var mongoose = require('mongoose');
var ItemSchema = mongoose.Schema({
text : String,
position: Number
});
// before validation starts, the number of Items is counted..afterwards, the position is set
ItemSchema.pre("validate", function(next) {
var doc = this;
// if 'position' is not filled in, fill it in..not using !position because 0 might be a valid value
if(typeof position !== "number") {
// count the number of Items *
// use mongoose.model to fetch the model because the model is not compiled yet
mongoose.model("Item").count(function(err, num) {
// if there was an error, pass it to next()
if(err)
return next(err);
// set the position, then call next();
doc.position = num;
return next();
});
} else if(this.isModified("position") || this.isNew()) {
// check if there is an existing document with the same position
// use mongoose.model to fetch the model because the model is not compiled yet
mongoose.model("Item").where({_id: {$ne: this._id}, position: this.position}).count( function (err, count) {
// if there was an error, pass it to next()
if(err)
return next(err);
// if there is a doc with the same position, execute an update to move down all the $gte docs
if(count > 0) {
// use mongoose.model to fetch the model because the model is not compiled yet
mongoose.model("Item").update({position: {$gte: this.position}}, {position: {$inc: 1}}, {multi: 1}, function(err, numAffected) {
// Call next() (with or without an error)
next(err);
});
} else {
// there are no docs that need to move down, so call next()
next();
}
});
} else {
// there is no need to count or update positions, so call next()
next();
}
});
module.exports = mongoose.model('Item', ItemSchema);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.