我试图做一些看似简单的事情,每次获取值时都会在MongoDB中更新一个视图计数器。
例如,我已经尝试过这种方法。
Meteor.methods({
'messages.get'(messageId) {
check(messageId, String);
if (Meteor.isServer) {
var message = Messages.findOne(
{_id: messageId}
);
var views = message.views;
// Increment views value
Messages.update(
messageId,
{ $set: { views: views++ }}
);
}
return Messages.findOne(
{_id: messageId}
);
},
});
但是我不能按照我的意图去工作。例如,if(Meteor.isServer)代码是无用的,因为它实际上并未在服务器上执行。
此外,在调用findOne后,该值似乎不可用,因此它可能是异步但findOne没有回调功能。
我不希望客户端控制这个部分,这就是我尝试在服务器端执行的原因,但每次客户端获取值时都需要执行。这听起来很难,因为客户已经订阅了数据。
编辑:这是在阅读完答案后的更新方法。
'messages.get'(messageId) {
check(messageId, String);
Messages.update(
messageId,
{ $inc: { views: 1 }}
);
return Messages.findOne(
{_id: messageId}
);
},
答案 0 :(得分:1)
例如if(Meteor.isServer)代码没用,因为它没有 实际上是在服务器上执行的。
Meteor方法总是在服务器上执行。您可以从客户端调用它们(使用回调),但执行发生在服务器端。
在调用findOne之后,值似乎也不可用, 所以它可能是异步但findOne没有回调功能。
你不需要两次打电话。请参阅以下代码:
Meteor.methods({
'messages.get'(messageId) {
check(messageId, String);
var message = Messages.findOne({_id:messageId});
if (message) {
// Increment views value on current doc
message.views++;
// Update by current doc
Messages.update(messageId,{ $set: { views: message.views }});
}
// return current doc or null if not found
return message;
},
});
您可以通过客户致电:
Meteor.call('messages.get', 'myMessageId01234', function(err, res) {
if (err || !res) {
// handle err, if res is empty, there is no message found
}
console.log(res); // your message
});
这里有两个补充:
为了可扩展性和数据封装,您可以将消息和视图拆分为单独的集合。如果您的发布方法不限于公共字段,那么请求消息的客户端也会收到视图计数。这可能现在有效,但可能会在更大范围内违反某些(未来即将发布的)访问规则。
答案 1 :(得分:0)
views++
表示:
views
的当前值,即使用当前(未修改的)值构建修饰符。views
的值,这在您的情况下不再有用,因为您不会将该变量用于其他任何内容。如果您不清楚它们是如何工作的,请避免使用这些增量运算符。
为什么不使用mongo $inc
运算符来避免必须检索以前的值?