I’m looking for a way to get a list of the unique values of a specific field.
The scenarios below are completely imaginary.
Let’s say I have answeredBy field in collection ClientCalls. It contains the username of who answered the call. Teh first phase is to get a list of all the users who answered calls today, in a publication. The next phase is to include the counts in a similar publication.
Let’s say there were 5k answered client calls today. There is a page where the manager selects from the list of who answered calls today. Then s/he sees that person’s answers to client calls.
So I want to get a list of personnel who answered calls today. I need to return unique values of ClientCalls.answeredBy.
I can easily do
var Records = ClientCalls.find({answeredDate: Today}, {fields: {Personnel: 1}}).fetch()
return _.uniq(_.pluck(Records, 'Personnel')
and this gives me the list I need, but doing this in a publication causes Error: Publish function returned an array of non-Cursors.
I could easily return all the calls in a publication and do the uniq on the clientside, but it would mean a lot of unnecessary resource usage.
In the Meteor docs, it says to use .find() to create cursors.
So, how do I return a list of unique usernames as a cursor?
You can use the distinct method. However, this is not available in minimongo, so you will need to use Collection.rawCollection().distinct() on the server.
I got object if not a function for rawCollection()., so I used rawCollection..
Then I got Can only call rawCollection on server collections, so I moved the collection definition under the server/ folder.
Yet I still get the same error message. The collection is not defined anywhere else, but I still the get the same error message.
In lib/Demo.js
Demo = new Mongo.Collection('demo');
In server/demo.js
Meteor.startup(function() {
if (Demo.find().count() === 0) {
Demo.insert({name:'Bob',customer:'ACME',value:1234.56});
Demo.insert({name:'Ted',customer:'ACME',value:5432.10});
Demo.insert({name:'Ted',customer:'Oops',value:543.21});
Demo.insert({name:'Bob',customer:'Spot',value:999.99});
}
});
Demo.rawCollection().distinct('name', (err,res) => {
console.log(res);
});
Outputs
I20160324-11:49:09.664(0)? [ 'Bob', 'Ted' ]
rawCollection() methods use standard node (error, result) callbacks, so you will need to use wrapAsync to use them productively in Meteor:
const distinct = Meteor.wrapAsync(Demo.rawCollection().distinct, Demo.rawCollection());
const result = distinct('name');
console.log(result);
1 Like