J Ho
J Ho

Reputation: 83

mongodb distinct() implementation in Meteor on the server?

I need to fetch distinct values from the mongodb in Meteor (basically, implementing mongodb native distinct() call). On client side, Does Meteor have a distinct query for collections? - this works like a charm. But I can't figure out how to get something similar to work on the server side. Appreciate any help. Thanks!

Upvotes: 1

Views: 2121

Answers (2)

Eric Chen
Eric Chen

Reputation: 63

In case anyone is trying this in Meteor v1.0+ (1.0.2), this code worked for me, I put it on the server. Basically the same as J Ho's answer with the tweaks mentioned - Npm.require, as well as the Future['return']. Cleaned up just a little for the Coffeescripters out there.

I was considering the package, but already had meteorhacks:aggregate package (only aggregate function), thus didn't want to chance overwriting it with another package. So, I just rolled my own distinct from the help of everyone else.

Hope this helps someone! Most likely, if I continue to use distinct on more collections, I'll use _.extend Meteor.Collection like here: https://github.com/zvictor/meteor-mongo-server/blob/master/server.coffee

path = Npm.require('path')
Future = Npm.require(path.join('fibers', 'future'))

myCollection = new Meteor.Collection "my_collection"

myCollection.distinct = (key, query) ->
  future = new Future
  @find()._mongo.db.createCollection @_name, (err,collection) =>
    future.throw err if err

    collection.distinct key, query, (err,result) =>
      future.throw(err) if err
      future['return']([true,result]) 

  result = future.wait()
  throw result[1] if !result[0]
  result[1]

Upvotes: 2

J Ho
J Ho

Reputation: 83

Ok after some digging around the code and realizing mongo lib contains native implementations of all the needed methods I reused the aggregate() solution from https://github.com/meteor/meteor/pull/644

Straightforward changes and translation to coffeescript gives the following snippet to put into your server side code:

path = __meteor_bootstrap__.require("path")
MongoDB = __meteor_bootstrap__.require("mongodb")
Future = __meteor_bootstrap__.require(path.join("fibers", "future"))

myCollection = new Meteor.Collection "my_collection"

#hacky distinct() definition from https://github.com/meteor/meteor/pull/644
myCollection.distinct = (key)->
  future = new Future
  @find()._mongo.db.createCollection(@_name,(err,collection)=>
    future.throw err if err
    collection.distinct(key, (err,result)=>
      future.throw(err) if err
      future.ret([true,result])
      )
    )
  result = future.wait()
  throw result[1] if !result[0]
  result[1]

Downside is you have to define it for every new collection but that's pretty straightforward to fix with another hack via _.extend or something I guess...

PS It's also now a smart package - mrt add mongodb-aggregation

Upvotes: 3

Related Questions