Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Projection generator for mongodb
_ = require 'underscore'
# Given an array of elements ELEM and a matching KEY value,
# will build the apprpriate projection to generate sortable
# weights for a mongo aggregator.
#
# ELEM: An array of values upon which to match against KEY
# KEY: The document field key to match against
# I: Default 0, index into array at which to begin
#
# Will return formatted projections. Note that elems must
# contain at least two elements for the initial call, else
# only the initial I value will be returned.
buildProjection = (elems, key, i = 0) ->
return i if (elems.length - i) == 1
$cond:
if: { $eq: [ "$#{key}", elems[i] ] }
then: i
else: buildProjection elems, key, i+1
# Assuming we have a mongoose userSchema, with the standard
# schema paths defined on userSchema.paths, we can make use
# of that objects keys to prevent $project from masking fields
# and then build our weights againsts the email key.
#
# Example.
#
# exampleQuery 'lmj112@ic.ac.uk', 'amv1882@ic.ac.uk'
# => [User(lmj112), User(amv1882)]
#
# Calling exec() simply generates a promise.
exampleQuery = (emails...) ->
projection =
_.object ([k,1] for own k,v of userSchema.paths)
projection.weight = buildProjection(emails, 'email')
User.aggregate([
{ $match: email: $in: emails }
{ $project: projection }
{ $sort: weight: 1 }
]).exec()
users = ['lmj112', 'amv1882', 'thb12']
console.log(JSON.stringify (buildProjection users, 'login'), undefined, 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.