Node和Mongoose创建/使用字段,为每个新添加的内容增加+1

时间:2013-09-04 18:12:12

标签: javascript mongoose

我会尽量保持这个简单。我花了一整天的时间来测试模块来做这件事,而且在这一点上我已经把它弄得一团糟,我认为这将是我最好的选择。

我有一个架构:

var AppSchema = new mongoose.Schema({
    appid: { type: Number },
    appname: { type: String },
    appdesc: { type: String }
});
app.db.model('userApp', AppSchema);

使用Express并处理POST,然后我想创建“一个新的应用程序”

app.post('/app/new', function (req, res) {
    var newApp = app.db.models.userApp({
        appid: functionToIncreaseByOne(),
        appname: req.param('appname'),
        appdesc: req.param('appdesc')
    });
    newApp.save();
});

我删除了那里的大部分膨胀,重定向等,只是为了保持这个简单。所以我想要做的是首先将APPID设置为1添加第一个应用程序,然后为每个添加的新应用程序增加+1。这看起来很简单,但我已经经历了很多复杂的例子,我的脑袋现在只是疼。

我想过只使用.find然后orderby找到具有最高appid的应用程序,然后只使用它并为其添加+1,但我确信必须有另一种更简单的方法。我不希望appid在有更新时更改,我想要设置它的唯一时间是在第一个POST路由上创建新应用程序。

如果有人可以帮助我,或者至少指出我正确的方向,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

我可以看到几种方法。

首先,您可以将last_id存储在全局变量中:

var last_id = 0;

app.post('/app/new', function (req, res) {
  var newApp = app.db.models.userApp({
    appid: ++last_id,
    appname: req.param('appname'),
    appdesc: req.param('appdesc')
  });
  newApp.save();
});

您可以添加last_id的正确初始化,以便在应用程序启动时“赶上”您的数据库。

这种方法的唯一缺点是,如果您有多个node.js进程,则无法使用它。

第二,您可以在每次要创建新文档时查询数据库:

app.post('/app/new', function (req, res, next) {
  app.db.models.userApp.find()
    .sort({_id: -1})
    .limit(1)
    .select('_id')
    .exec(function (err, docs) {
      if (err) return next(err);
      var newApp = app.db.models.userApp({
        appid: docs[0]._id,
        appname: req.param('appname'),
        appdesc: req.param('appdesc')
      });
      newApp.save();
    })
});

但是无法保证在上一次find操作之后将发生下一个save操作。因此,您的应用有可能会尝试使用一个_id保存两个不同的文档。这就是为什么你应该尽可能避免这种解决方案。

第三次,您每次阅读时都可以使用其他存储空间(例如Redis)以原子方式递增last_id

var RedisClient = require('redis').createClient()

app.post('/app/new', function (req, res, next) {
  RedisClient.incr('last_id', function (err, next_id) {
    if (err) return next(err);
    var newApp = app.db.models.userApp({
      appid: next_id,
      appname: req.param('appname'),
      appdesc: req.param('appdesc')
    });
    newApp.save();
  })
});

此解决方案是最好的解决方案,但需要安装其他数据库。