Meteor collection 观察用户 activity 日志
Meteor collection observe user activity log
您好,我正在尝试观察 collection 上的更改并保存更改日志,我在创建 collection 后立即设置观察,问题是,我不能弄清楚如何知道哪个用户进行了更改,我尝试将观察者放在发布方法上,但它会生成多个观察者并在只完成一件事时在日志上创建许多条目,之后我将句柄保存到观察者以防止多个观察者,但是无论我登录哪个用户,日志都保存在第一个订阅发布的用户的名字中,我不想为每个用户创建一个观察者并删除观察者动态处理,我很确定在服务器上会非常紧张,必须有更好的方法。也许在客户端设置观察者?但我不希望客户端访问日志 collection.
Products = new Mongo.Collection("products");
Log = new Mongo.Collection("log");
var initializing = true;
Products.find().observe({
added: function(newDocument) {
if (initializing) return;
//how to get user here?
Log.insert({
idUser: ???,
date: new Date(),
document: newDocument
});
}
});
initializing = false;
这是我的第一次尝试,以下是我在发布时的尝试方式:
var productsObserveHandle;
Meteor.publish('products', function() {
var initializing = true;
if (!productsObserveHandle) {
productsObserveHandle = Products.find().observe( {
added: function (document) {
if (initializing) return;
var userProfile = Meteor.users.findOne({_id:this.userId}).profile;
Log.insert( {
idUser: this.userId,
userProfile: userProfile,
date: new Date(),
eventType: "added",
document: document
});
}.bind(this)
});
}
initializing = false;
...
});
这个几乎搞定了,但它总是将日志保存为同一用户,无论我尝试多少个不同的用户,因为已经创建了观察者句柄。
更新:好的,我想我有所进展,我在 collection 订阅后在客户端设置了观察,然后是所有观察方法 added
、changed
, removed
调用流星方法,保存日志并通过 Meteor.userId()
获取用户并且它有效,但现在的情况是,当你注销并登录时,minimongo 数据库得到更新,但是订阅是相同的(我在客户端 Meteor.startup 上进行所有订阅),所以我无法停止观察者并在更新后重新启动它,有没有办法知道何时更新 minimongo 因为账户变更?我可以尝试在用户注销后删除观察者并在登录后等待超时以再次设置观察者,但我发现这有风险,因为更新 minimongo 可能需要比我设置的超时更多的时间并且最后的插入可能会泄漏到更改日志。
这并没有直接回答您的问题,而是提供了替代解决方案。我经常在我的流星应用程序中实现这种模式,并且我总是使用 Collection Hooks 包。
更具体地说,您可以使用 .after.insert(userId, doc)
and .after.update(userId, doc, fieldNames, modifier, options)
方法。两者都正确处理了用户 ID。
如果您不想为此使用包,那么您应该能够看到他们是如何解决您的问题的,因为需要它才能使包正常工作。
您好,我正在尝试观察 collection 上的更改并保存更改日志,我在创建 collection 后立即设置观察,问题是,我不能弄清楚如何知道哪个用户进行了更改,我尝试将观察者放在发布方法上,但它会生成多个观察者并在只完成一件事时在日志上创建许多条目,之后我将句柄保存到观察者以防止多个观察者,但是无论我登录哪个用户,日志都保存在第一个订阅发布的用户的名字中,我不想为每个用户创建一个观察者并删除观察者动态处理,我很确定在服务器上会非常紧张,必须有更好的方法。也许在客户端设置观察者?但我不希望客户端访问日志 collection.
Products = new Mongo.Collection("products");
Log = new Mongo.Collection("log");
var initializing = true;
Products.find().observe({
added: function(newDocument) {
if (initializing) return;
//how to get user here?
Log.insert({
idUser: ???,
date: new Date(),
document: newDocument
});
}
});
initializing = false;
这是我的第一次尝试,以下是我在发布时的尝试方式:
var productsObserveHandle;
Meteor.publish('products', function() {
var initializing = true;
if (!productsObserveHandle) {
productsObserveHandle = Products.find().observe( {
added: function (document) {
if (initializing) return;
var userProfile = Meteor.users.findOne({_id:this.userId}).profile;
Log.insert( {
idUser: this.userId,
userProfile: userProfile,
date: new Date(),
eventType: "added",
document: document
});
}.bind(this)
});
}
initializing = false;
...
});
这个几乎搞定了,但它总是将日志保存为同一用户,无论我尝试多少个不同的用户,因为已经创建了观察者句柄。
更新:好的,我想我有所进展,我在 collection 订阅后在客户端设置了观察,然后是所有观察方法 added
、changed
, removed
调用流星方法,保存日志并通过 Meteor.userId()
获取用户并且它有效,但现在的情况是,当你注销并登录时,minimongo 数据库得到更新,但是订阅是相同的(我在客户端 Meteor.startup 上进行所有订阅),所以我无法停止观察者并在更新后重新启动它,有没有办法知道何时更新 minimongo 因为账户变更?我可以尝试在用户注销后删除观察者并在登录后等待超时以再次设置观察者,但我发现这有风险,因为更新 minimongo 可能需要比我设置的超时更多的时间并且最后的插入可能会泄漏到更改日志。
这并没有直接回答您的问题,而是提供了替代解决方案。我经常在我的流星应用程序中实现这种模式,并且我总是使用 Collection Hooks 包。
更具体地说,您可以使用 .after.insert(userId, doc)
and .after.update(userId, doc, fieldNames, modifier, options)
方法。两者都正确处理了用户 ID。
如果您不想为此使用包,那么您应该能够看到他们是如何解决您的问题的,因为需要它才能使包正常工作。