【问题标题】:an error about tailable cursor for a query in mongoose关于 mongoose 中查询的可尾游标的错误
【发布时间】:2014-07-16 03:36:36
【问题描述】:

用户模型包含 SubscriptionSchema 和 AccessToken Schema,我也用{capped : 234556} 定义了这两个插件模式。

   var User = new Schema({
     email                  : String
   , firstName              : String
   , password               : String
   , isAdmin                : Boolean
   , lastSeen               : Date
   , subscriptions          : [ SubscriptionSchema ]
   , accessTokens           : [ AccessToken ]
   }, {
    toObject : { virtuals : true }
   , toJSON   : { virtuals : true }
   , capped   : 234556
   });

   var streamTest = User.find().limit(1).tailable().stream();

当我尝试运行上面的代码时,我仍然得到错误:

MongoError: tailable cursor requested on non capped collection

【问题讨论】:

    标签: javascript node.js mongodb mongoose stream


    【解决方案1】:

    这看起来不像是对有上限的集合或可尾流的正确使用。但也许先写一段代码来演示一个工作示例:

    var async = require('async'),
        mongoose = require('mongoose'),
        Schema = mongoose.Schema;
    
    var userSchema = new Schema({
      email: String,
    },{
      capped: 2048
    });
    
    var User = mongoose.model( "User", userSchema );
    
    
    mongoose.connect('mongodb://localhost/atest');
    
    var stream;
    
    async.waterfall(
      [
        function(callback) {
          var user = new User({ email: "existing" });
          user.save(function(err,doc) {
            if (err) throw err;
            callback();
          });
        },
    
        function(callback) {
          User.find({}).sort({ "$natural": -1 }).limit(1).exec(function(err,docs) {
            if (err) throw err;
            console.log( docs );
            callback(err,docs[0]);
          });
        },
    
        function(doc,callback) {
          stream = User.find({ "_id": { "$gt": doc._id } }).tailable().stream();
          stream.on("data",function(doc) {
            console.log( "Streamed:\n%s", doc );
          });
          callback();
        },
    
        function(callback) {
          async.eachSeries(
            ['one','two','three'],
            function(item,callback) {
              var user = new User({ email: item });
              user.save(function(err,doc) {
                if (err) throw err;
                console.log( "Saved:\n%s", doc );
                callback();
              });
            },
            function(err) {
              if (err) throw err;
              callback();
            }
          );
        }
      ]
    );
    

    首先,在 capped 集合中确实需要一些东西才能正常工作。这假定该集合不存在并且它将被初始化为一个上限集合。然后第一步是确保有东西。

    一般当你想“尾”时,你只希望插入的新文档出现。因此,在设置可拖尾光标之前,您需要在集合中找到“最后一个”文档。

    当您知道集合中的最后一个文档时,“tailable 流”会设置为查找“大于”该文档的任何内容,即新文档。如果您不这样做,则流上的第一个“数据”事件将清空所有当前集合项。所以这里.sort().limit() 的选项不适用。尾随游标初始化并“跟随”。

    现在已经设置了流接口并建立了侦听器,您可以将项目添加到流中。然后这些将相应地记录,但由于这是“事件”,因此这里的记录没有特定的顺序,因为“保存”或“流”数据事件实际上可能首先触发。


    现在开始您的实施。这两行很突出:

       , subscriptions          : [ SubscriptionSchema ]
       , accessTokens           : [ AccessToken ]
    

    那些包含嵌入式数组,它们不是另一个集合中的“外部”文档,即使它是否存在也没关系。这里的一般问题是你(至少在某种程度上)引入了一个数组,它似乎暗示了一些“成长”的概念。

    除非您的意图是从不“增长”这些数组并且只在新文档中插入内容并且从不更新它,否则这将导致上限集合出现问题。

    上限集合中的文档不能“增长”超过其初始分配的大小。尝试更新发生这种情况的位置会导致错误。如果您认为自己会很聪明并“填充”您的文档,那么当复制的辅助主机“重新同步”时,这很可能会失败。所有记录都带有上限。

    【讨论】:

    • 首先,非常感谢你的代码。您对如何在猫鼬中使用cappedtail 有很好的解释。这对我帮助很大。
    猜你喜欢
    • 2012-11-02
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多