I have made a collection
var Words = new Meteor.Collection(\"words\");
and published it:
Meteor.publish(\"words\", functio
You could assemble the counts by going through each document in Words, (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);
});
create a local collection,
var counts = new Meteor.Collection('local-counts-collection', {connection: null});
and insert your answers
var key, value;
for (key in wordCounts) {
value = object[key];
counts.insert({
length: key,
count: value.count,
members: value.words
});
}
Counts is now a collection, just not stored in Mongo.
Not tested!
To wrap transformations mentioned in other answers, you could use the package I developed, meteor-middleware. It provides a nice pluggable API for this. So instead of just providing a transform, you can stack them one on another. This allows for code reuse, permissions checks (like removing or aggregating fields based on permissions), etc. So you could create a class which allows you to aggregate documents in the way you want.
But for your particular case you might want to look into MongoDB aggregation pipeline. If there is really a lot of words you probably do not want to transfer all of them from the MongoDB server to the Meteor server side. On the other hand, aggregation pipeline lacks the reactivity you might want to have. So that published documents change counts as words come in and go.
To address that you could use another package I developed, PeerDB. It allows you to specify triggers which would be reactively called as data changes, and stored in the database. Then you could simply use normal publishing to send counts to the client. The downside is that all users should be interested in the same collection. It works globally, not per user. But if you are interested in counts of words per whole collection, you could do something like (in 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
And then you could simply publish WordCounts
documents:
Meteor.publish 'counts', ->
WordCounts.documents.find()
UPDATE You can transform a collection on the server like this:
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();
});