Reputation: 335
i need exactly this map/reduce function in meteor: http://cookbook.mongodb.org/patterns/count_tags/
Read all tags from all entries and give back a list of unique tags with the amount in the collection
How would I implement this. I'm using standalone Mongodb. Collection Layout:
[_id] => 1234
[headline] => My First Post
[body] => Alot of stuff
[isPrivat] =>
[tags] => Array (
[0] => test
[1] => php
[2] => perl
)
I found this question/answer, but I can't get this to do what I wan't :
Does Meteor have a distinct query for collections?
What is the most elegant way to do this. Thank you for your time
Upvotes: 4
Views: 2561
Reputation: 13643
You could try the meteor-mongo-extensions smart package, which implements some of MongoDB's aggregation framework functions for Meteor (disclaimer: I haven't tried it myself).
Another solution you might find helpful is sketched in pull request #644.
Upvotes: 2
Reputation: 335
I used the a.js lib to have the distinct code search suggested from here. Does Meteor have a distinct query for collections?
And this ugly one:
Template.Tag.taglist = function () {
var taglist = Posts.find({}).distinct("tags");
taglist = _.compact(_.flatten(_.pluck(taglist, 'tags')));
// reformat, count and filter doublets
function counttags(arr) {
var a = [], b = [], prev;
arr.sort();
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
result = _.zip(a,b);
return result;
}
var taglist = counttags(taglist);
//console.log(taglist);
return taglist;
};
and the (simplified) template:
<template name="Tag">
{{#each taglist}}
{{this.[0]}}x {{this.[1]}}
{{/each}}
</template>
It's not very beautiful. once the aggregate or map/reduce methods are available I will swap the code. But for prototyping this works. Thanks everyone.
Upvotes: 1
Reputation: 53685
At the current moment, the most elegant solution would be aggregation framework:
db.items.aggregate(
{ $unwind : "$tags" },
{ $group : {
_id : "$tags",
count: { $sum : 1 }
}}
);
It will output result like this one:
{ "result" : [
{ "_id" : "perl",
"count" : 2 },
{ "_id" : "php",
"count" : 1 },
{ "_id" : "test",
"count" : 1 }],
"ok" : 1 }
This is mongodb shell syntax. I not familiar with meteor, so I'll not try to write some code. Hope this helps!
Upvotes: 8