我试图在调度应用程序中使用Mongoose及其查询流,但也许我误解了它是如何工作的。我已经在SO [Mongoose QueryStream new results上阅读了这个问题,看起来我是对的,但有人请解释一下:
如果我正在过滤这样的查询 -
Model.find().stream()
当我添加或更改与.find()
匹配的内容时,它应该抛出data
个事件,对吗?或者我对这个问题的理解完全错了吗?
例如,我试图查看一些类似的数据:
Events.find({'title':/^word/}).stream();
我在mongodb控制台中更改了标题,但没有看到任何更改。
任何人都可以解释原因吗?
答案 0 :(得分:2)
您的理解确实不正确,因为流只是当前查询响应的输出流,而不是“自己监听新数据”的内容。这里返回的结果基本上只是一个节点streaming interface,这是一个可选的选择而不是“游标”,或者实际上是默认情况下mongoose方法直接转换为数组。
所以“流”不只是“跟随”任何东西。它只是处理查询的正常结果的另一种方式,但其方式是不会立即将所有结果“淹没”到内存中。它使用事件侦听器来处理从服务器游标中获取的每个结果。
您实际上在谈论的是"tailable cursor"或其中的一些变体。在基本的MongoDB操作中,可以在capped collection上实现“tailable cursor”。这是一种特殊类型的集合,具有特定的规则,因此可能不适合您的目的。它们用于“仅插入”操作,通常适用于事件队列。
在使用上限集合的模型上(并且仅在设置了上限集合的位置),然后执行如下:
var query = Events.find({'title':/^word/}).sort({ "$natural": -1}).limit(1);
var stream = query.tailable({ "awaitdata": true}).stream();
// fires on data received
stream.on("data",function(data) {
console.log(data);
});
“awaitdata”与“tailable”选项本身一样重要,因为它是主要的事情,告诉查询光标保持“活动”和“尾”添加到符合查询条件。但是你的收藏必须“限制”才能使其发挥作用。
另一种更高级的方法是执行类似meteor分发的操作,其中被绑定的“上限集合”实际上是MongoDB oplog。这需要replica set配置,但正如流星开箱即用,将单个节点作为副本集本身没有任何问题。在生产中这样做是不明智的。
这比简单的答案更为广泛,但基本概念是因为“oplog”是一个上限集合,您可以为数据库上的所有写操作“拖尾”它。然后检查此事件数据以确定已写入要监视写入的集合的详细信息。然后,该数据可用于查询新信息,并通过websocket或类似工具将更新或新结果返回给客户端。
但是流本身就只是一个流。要“跟踪”集合上的更改,您需要将其实现为上限,或者考虑根据所述的oplog中的更改来实现流程。