我有一个发布,它返回一个如下所示的游标:
// Publication RETURNS THIS QUERY
Notepads.find({_id: notepadId, $or: [{userId: this.userId}, {'collaborators.userId': this.userId}], archived: false})
正如您所看到的,查询对用户来说是唯一的,因为它包含this.userId
我在出版物中使用this.userId
作为安全形式。如果您与该特定记事本相关联,则只会返回数据。
在我的应用中,多人可以在一个记事本上进行协作。那么为了使观察者更可重复使用,这种调整是否有助于我的应用?
// Optimized publication
notepad = Notepads.findOne({_id: notepadId, $or: [{userId: @userId}, {'collaborators.userId': @userId}], archived: false})
if notepad?
// Optimized publication RETURNS THIS QUERY
return Notepads.find({_id: notepad._id, archived: false})
else
return
我认为这是观察者重用的意思。该发布为订阅它的任何用户返回完全相同的查询。这是正确的,这种优化值得改变吗?
答案 0 :(得分:0)
Quoting from kadira.io on How Observers are Handled in Meteor:
为了创建相同的观察者,您需要创建游标 用:
- 同一集合
- 相同的选择器(查询)
- 同一组选项(包括排序,限制等)
在您的示例中,不同用户的选择器不同。
选择器为Object Literals并在传递到.find调用之前进行评估。这意味着{_id: notepad._id, archived: false}
变为
{_id: 'myNotebookID', archived: false}
或{_id: 'anotherNotebookId', archived: false}
。 正如您所看到的,在您解析notepad._id
后,这些是不同的选择器,这在传递给.find()之前就会发生。
如果您的第一个数据库查询返回了相同的记事本,因为您的第二个用户是第一个用户笔记本上的协作者,您最终会得到相同的选择器和一个游标/可观察对象。然而,对于大多数应用程序而言,这可能不足以进行优化,尤其是(如@Khang指出)您将失去反应性。
所以,它不是同一个查询,它不会重复使用观察者,并且不值得改变。
答案 1 :(得分:0)
您的优化版本存在问题,即不响应。因为您使用Notepads.findOne
作为安全检查来确保用户可以访问该文档。
内部发布.findOne
不是被动的,例如在执行发布时,用户无权访问该文档,因此没有任何内容发送给客户端,然后将用户添加为协作者,但不做任何更改,因为出版物将重新运行。