UNPKG

filterable

Version:
112 lines (94 loc) 3.15 kB
var _ = require("lodash"); var TYPES = { "!=": "$ne", "=": "", ">": "$gt", ">=": "$gte", "<": "$lt", "<=": "$lte", "in": "$in", "nin": "$nin" }; function convert(query) { var mongoQ = {}; // Query apply to all var queryAll = {}; // OR query var queryOr = {}; // Append a group to the query function appendGroup(group, fn) { if (_.isArray(group.field)) { queryOr[group.originalField] = queryOr[group.originalField] || {}; _.each(group.field, function(field) { queryOr[group.originalField][field] = queryOr[group.originalField][field] || {}; queryOr[group.originalField][field] = fn(queryOr[group.originalField][field]); }); } else { queryAll[group.field] = fn(queryAll[group.field]); } } // Convert all groups _.each(query.groups, function(group) { // Equals if (group.type == "=") { appendGroup(group, _.constant(group.value)); } // in or nin else if (group.type == "in" || group.type == "nin") { var mType = "$"+group.type; queryAll[group.field] = queryAll[group.field] || {}; queryAll[group.field][mType] = queryAll[group.field][mType] || []; queryAll[group.field][mType].push(group.value); queryAll[group.field][mType] = _.flatten(queryAll[group.field][mType]); } // simplify "!= true" to "= false" else if (group.type === "!=" && group.value === true) { group.type = "="; group.value = false; appendGroup(group, _.constant(group.value)); } // Other types else if (TYPES[group.type]) { appendGroup(group, function(value) { value = value || {}; value[TYPES[group.type]] = group.value; return value; }); } // Invalid type else { throw ("Invalid type for mongo query: "+group.type); } }); mongoQ = queryAll; if (_.size(queryOr) == 1) { mongoQ["$or"] = _.chain(queryOr) .values() .first() .map(function(value, field) { return _.object([field], [value]); }) .value(); } if (_.size(queryOr) > 1) { var finalOr = []; var added = []; _.each(queryOr, function(alias, originalField) { if (_.contains(added, originalField)) return; _.each(alias, function(values, alia) { _.each(_.omit(queryOr, originalField), function(otherFields, otherBaseField) { _.each(otherFields, function(otherValue, otherField) { var nOr = {}; nOr[alia] = values; nOr[otherField] = otherValue; finalOr.push(nOr); }); added.push(otherBaseField); }); }); }); mongoQ["$or"] = finalOr; } return mongoQ; }; module.exports = convert;