用户模型为Consub 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

最佳答案

看起来不像是上限集合或可尾流的正确用法。但是,也许首先需要一些代码来演示一个有效的示例:

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();
        }
      );
    }
  ]
);


首先,在封顶的收藏集中确实需要有一些东西才能起作用。这假定该集合不存在,并且它将被初始化为一个有上限的集合。然后第一步就是确保有东西存在。

通常,当您要“拖尾”时,您只希望显示插入的新文档。因此,在设置可尾光标之前,您要在集合中查找“最后一个”文档。

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

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



现在进入您的实现。这两行脱颖而出:

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


这些包含嵌入式数组,它们即使在另一个集合中也没有关系,它们不是另一个集合中的“外部”文档。这里的一般问题是,您(至少以某种方式)引入了一个数组,这似乎暗示一些关于“增长”的概念。

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

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

08-15 16:16