Reputation: 503
I am trying to return a collection (Postings) grouped by a field (status). I am pretty new to mongo and meteor. The query below gives me the collections grouped by status with # of docs by that status... basically I want the same thing but have the actual documents in there.
Also, I would like to be able to publish/subscribe to this so that they reactivly update. I am creating an admin dashboard that groups all the Postings by current status.
A friend provided the following gist, but it is a bit over my head: https://gist.github.com/ryw/8827179
db.postings.group({ key: {status: 1}, initial: {sum:0}, reduce: function(doc, prev) { prev.sum += 1; } })
Thanks!
Upvotes: 2
Views: 571
Reputation: 64312
If you need all of the documents on the client, then I would just publish the whole collection and let the template code group them.
Tracker.autorun(function() {
if (Meteor.user()) {
Meteor.subscribe('allPostings');
}
});
Template.admin.helpers({
postings: function() {
if (Session.get('currentStatus')) {
return Postings.find({status: Session.get('currentStatus')});
}
},
statuses: function() {
return _.uniq(_.pluck(Postings.find().fetch(), 'status'));
}
});
Template.admin.events({
'click .status': function() {
Session.set('currentStatus', String(this));
}
});
<template name="admin">
<div class="left-panel">
<ul>
{{#each statuses}}
<li class="status">{{this}}</li>
{{/each}}
</ul>
</div>
<div class="right-panel">
<ul>
{{#each postings}}
<li>{{message}}</li>
{{/each}}
</ul>
</div>
</template>
Meteor.publish('allPostings', function() {
var user = Meteor.users.findOne(this.userId);
if (user.isAdmin) {
return Postings.find();
}
});
I'm assuming you have some way to identify admin users (here I used isAdmin
). I am also assuming that a posting has a status
and a message
.
Upvotes: 1
Reputation: 5472
Instead of using aggregate functions or map reduce operations, you could denormalize your data and store a separate collection of the groups and their counts.
You can update your counts using observe functions as in the following example from the relevant section of meteor docs:
// Keep track of how many administrators are online.
var count = 0;
var query = Users.find({admin: true, onlineNow: true});
var handle = query.observeChanges({
added: function (id, user) {
count++;
console.log(user.name + " brings the total to " + count + " admins.");
},
removed: function () {
count--;
console.log("Lost one. We're now down to " + count + " admins.");
}
});
// After five seconds, stop keeping the count.
setTimeout(function () {handle.stop();}, 5000);
This way, you can present the groups and their counts on a template and it would be reactive.
Upvotes: 0