【问题标题】:Node and Mongoose create/use field that increases +1 for each new added节点和猫鼬创建/使用字段,每增加一个新添加的字段就会增加 +1
【发布时间】:2013-09-05 04:24:09
【问题描述】:

我会尽量保持简单。我花了一整天的时间测试模块来做这件事,在这一点上,我对我认为这是我最好的选择的一切都感到困惑。

我有一个架构:

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 路由上创建新应用程序。

如果有人可以在这里帮助我或至少为我指明正确的方向,我将不胜感激。

【问题讨论】:

    标签: javascript mongoose


    【解决方案1】:

    我可以看到几种方法。

    首先,您可以将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();
      })
    });
    

    这个解决方案是最好的,但它需要安装额外的数据库。

    【讨论】:

    • 完美,Redis 绝对是最佳选择,哇,这太容易了!非常感谢您的解释和回复……我早就应该使用redis了!再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2020-10-15
    • 2018-08-26
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 2019-11-22
    • 2012-02-17
    • 2020-06-25
    相关资源
    最近更新 更多