我制作了一个集合
var Words = new Meteor.Collection("words");
并发布:
Meteor.publish("words", function() {
return Words.find();
});
以便我可以在客户端上访问它。问题是,这个集合会变得非常大,我只想发布它的变换。例如,假设我想发布一个名为“num words by length”的摘要,这是一个int数组,其中索引是单词的长度,item是该长度的单词数。所以
wordsByLength[5] = 12;
表示有12个长度为5的单词。在SQL术语中,它比原始数据集简单的GROUP BY / COUNT。我正在尝试在客户端上创建一个类似
的模板每个长度。我的问题归结为“我的表格A中有我的数据,我想发布一个转换后的版本,B”。
答案 0 :(得分:21)
UPDATE 您可以在服务器上转换集合,如下所示:
Words = new Mongo.Collection("collection_name");
Meteor.publish("yourRecordSet", function() {
//Transform function
var transform = function(doc) {
doc.date = new Date();
return doc;
}
var self = this;
var observer = Words.find().observe({
added: function (document) {
self.added('collection_name', document._id, transform(document));
},
changed: function (newDocument, oldDocument) {
self.changed('collection_name', oldDocument._id, transform(newDocument));
},
removed: function (oldDocument) {
self.removed('collection_name', oldDocument._id);
}
});
self.onStop(function () {
observer.stop();
});
self.ready();
});
答案 1 :(得分:1)
要包装其他答案中提到的转换,您可以使用我开发的包meteor-middleware。它为此提供了一个很好的可插拔API。因此,您可以将它们堆叠在另一个上,而不仅仅是提供转换。这允许代码重用,权限检查(比如根据权限删除或聚合字段)等。因此,您可以创建一个类,允许您以您希望的方式聚合文档。
但是对于您的特定情况,您可能需要查看MongoDB aggregation pipeline。如果确实有很多单词,您可能不希望将所有单词从MongoDB服务器传输到Meteor服务器端。另一方面,聚合管道缺乏您可能想要的反应性。因此,发布的文档会随着单词的进入而改变计数。
要解决这个问题,你可以使用我开发的另一个软件包PeerDB。它允许您指定将被动态调用为数据更改并存储在数据库中的触发器。然后,您可以简单地使用普通发布将计数发送到客户端。缺点是所有用户都应该对同一个集合感兴趣。它适用于全球,而非每个用户。但如果你对整个集合中的单词数量感兴趣,你可以做一些像(在CoffeesScript中):
class WordCounts extends Document
@Meta
name: 'WordCounts'
class Words extends Document
@Meta
name: 'Words'
triggers: =>
countWords: @Trigger ['word'], (newDocument, oldDocument) ->
# Document has been removed.
if not newDocument._id
WordCounts.update
length: oldDocument.word.length
,
$inc:
count: -1
# Document has been added.
else if not oldDocument._id
WordCounts.update
length: newDocument.word.length
,
$inc:
count: 1
# Word length has changed.
else if newDocument.word.length isnt oldDocument.word.length
WordCounts.update
length: oldDocument.word.length
,
$inc:
count: -1
WordCounts.update
length: newDocument.word.length
,
$inc:
count: 1
然后你可以简单地发布WordCounts
个文件:
Meteor.publish 'counts', ->
WordCounts.documents.find()
答案 2 :(得分:0)
您可以通过单词(cursor for each)
遍历每个文档来汇总计数var countingCursor = Words.find({});
var wordCounts = {};
countingCursor.forEach(function (word) {
wordCounts[word.length].count += 1;
wordCounts[word.length].words = wordCounts[word.length].words || []
wordCounts[word.length].words.push(word);
});
创建一个本地集合,
var counts = new Meteor.Collection('local-counts-collection', {connection: null});
并插入您的答案
var key, value;
for (key in wordCounts) {
value = object[key];
counts.insert({
length: key,
count: value.count,
members: value.words
});
}
Counts现在是一个集合,只是没有存储在Mongo中。
未经测试!