Last active
March 15, 2019 19:00
-
-
Save lawrencejones/e1ff8a85e32af6ff9a0e to your computer and use it in GitHub Desktop.
Projection generator for mongodb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_ = 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 '[email protected]', '[email protected]' | |
# => [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