流星:客户端查看页面时增加数据库值服务器端
Meteor: Increment DB value server side when client views page
我正在尝试做一些看似简单的事情,每次获取值时更新 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后好像没有这个值,所以可能是async,但是findOne没有回调功能。
我不希望客户端控制这部分,这就是为什么我试图在服务器端执行它,但它需要在客户端每次获取值时执行。这听起来很难,因为客户已经订阅了数据。
编辑:这是阅读此处答案后更新的方法。
'messages.get'(messageId) {
check(messageId, String);
Messages.update(
messageId,
{ $inc: { views: 1 }}
);
return Messages.findOne(
{_id: messageId}
);
},
For example the if(Meteor.isServer) code is useless because it's not
actually executed on the server.
Meteor 方法总是在服务器上执行。您可以从客户端调用它们(使用回调),但执行发生在服务器端。
Also the value doesn't seem to be available after findOne is called,
so it's likely async but findOne has no callback feature.
你不需要调用它两次。请看下面的代码:
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
});
这里补充两点:
为了可扩展性和数据封装,您可以将消息和视图拆分到单独的集合中。如果您的 publication 方法不限于 public 字段,那么请求消息的客户端也会收到查看计数。这可能暂时有效,但可能会在更大范围内违反某些(未来即将推出的)访问规则。
views++
表示:
- 使用
views
的当前值,即使用当前(未修改)值构建修饰符。
- 增加
views
的值,这对您的情况不再有用,因为您没有将该变量用于任何其他用途。
如果您不清楚这些增量运算符的具体工作原理,请避免使用它们。
为什么不使用 mongo $inc
运算符来避免必须检索以前的值?
我正在尝试做一些看似简单的事情,每次获取值时更新 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后好像没有这个值,所以可能是async,但是findOne没有回调功能。
我不希望客户端控制这部分,这就是为什么我试图在服务器端执行它,但它需要在客户端每次获取值时执行。这听起来很难,因为客户已经订阅了数据。
编辑:这是阅读此处答案后更新的方法。
'messages.get'(messageId) {
check(messageId, String);
Messages.update(
messageId,
{ $inc: { views: 1 }}
);
return Messages.findOne(
{_id: messageId}
);
},
For example the if(Meteor.isServer) code is useless because it's not actually executed on the server.
Meteor 方法总是在服务器上执行。您可以从客户端调用它们(使用回调),但执行发生在服务器端。
Also the value doesn't seem to be available after findOne is called, so it's likely async but findOne has no callback feature.
你不需要调用它两次。请看下面的代码:
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
});
这里补充两点:
为了可扩展性和数据封装,您可以将消息和视图拆分到单独的集合中。如果您的 publication 方法不限于 public 字段,那么请求消息的客户端也会收到查看计数。这可能暂时有效,但可能会在更大范围内违反某些(未来即将推出的)访问规则。
views++
表示:
- 使用
views
的当前值,即使用当前(未修改)值构建修饰符。 - 增加
views
的值,这对您的情况不再有用,因为您没有将该变量用于任何其他用途。
如果您不清楚这些增量运算符的具体工作原理,请避免使用它们。
为什么不使用 mongo $inc
运算符来避免必须检索以前的值?