我在meteor中使用MongoDB聚合。多次订阅时,我得到了重复的数据。
(数据库中的数据是静态的,这意味着它们始终是相同的。)
//服务器端
Meteor.publish('totalNumber', function () {
let pipeline = [
{ $unwind: '$product' },
{ $group: {
_id: {
code: '$product.code',
hour: { $hour: '$timestamp' }
},
total: { $sum: '$product.count' },
}}
];
Products.aggregate(
pipeline,
Meteor.bindEnvironment((err, result) => {
console.log('result', result); // at here every time subscribe, no duplicated data
_.each(result, r => {
this.added('totalNumber',
// I use Random.id() here, because "Meteor does not currently support objects other than ObjectID as ids"
Random.id(), {
code: r._id.code,
hour: r._id.hour,
total: r.total
});
});
}
)
);
this.ready();
});
//客户端
this.subscribe('totalNumber', () => {
// Correct result: [Object, Object] for example
console.log(Products.find().fetch());
}, true);
this.subscribe('totalNumber', () => {
// Wrong result: [Object, Object, Object, Object]
console.log(Products.find().fetch());
}, true);
this.subscribe('totalNumber', () => {
// Wrong result: [Object, Object, Object, Object, Object, Object]
console.log(Products.find().fetch());
}, true);
所以现在基本上,新结果总是包括上次订阅数据。
我该如何解决这个问题?感谢
答案 0 :(得分:1)
问题是您每次调用added
时都使用随机ID,因此客户端始终认为所有文档都是唯一的。您需要设计一个一致 id字符串生成器。使用this question的答案,您可以想象构建一组这样的函数:
hashCode = function (s) {
return s.split('').reduce(function (a, b) {
a = ((a << 5) - a) + b.charCodeAt(0);return a & a;
}, 0);
};
objectToHash = function (obj) {
return String(hashCode(JSON.stringify(obj)));
};
因此,如果您想为code
和hour
的每个组合创建一个独特的文档,那么您可以这样做:
var id = objectToHash(r._id);
this.added('totalNumber', id, {...});