New operator and extended dot operator document search

pull/2/head
lf250055 11 years ago
parent b4ae736d4d
commit d6eeb00d95
  1. 33
      lib/model.js

@ -12,6 +12,7 @@ var dateToJSON = function () { return { $$date: this.getTime() }; }
, lastStepModifierFunctions = {} , lastStepModifierFunctions = {}
, comparisonFunctions = {} , comparisonFunctions = {}
, logicalOperators = {} , logicalOperators = {}
, queryOperators = {}
; ;
@ -439,6 +440,12 @@ function getDotValue (obj, field) {
if (fieldParts.length === 1) { if (fieldParts.length === 1) {
return obj[fieldParts[0]]; return obj[fieldParts[0]];
} else if (util.isArray(obj[fieldParts[0]])) {
var objs = new Array();
for (var i = 0; i < obj[fieldParts[0]].length; i += 1) {
objs = objs.concat(getDotValue(obj[fieldParts[0]][i], fieldParts.slice(1).join('.')));
}
return objs;
} else { } else {
return getDotValue(obj[fieldParts[0]], fieldParts.slice(1)); return getDotValue(obj[fieldParts[0]], fieldParts.slice(1));
} }
@ -566,7 +573,6 @@ comparisonFunctions.$exists = function (value, exists) {
} }
}; };
/** /**
* Match any of the subqueries * Match any of the subqueries
* @param {Model} obj * @param {Model} obj
@ -613,6 +619,17 @@ logicalOperators.$not = function (obj, query) {
}; };
/**
*
* @param obj
* @param value
* @returns {*|boolean}
*/
queryOperators.$size = function (obj, value) {
return (util.isArray(obj) && obj.length == value);
};
/** /**
* Tell if a given document matches a query * Tell if a given document matches a query
* @param {Object} obj Document to check * @param {Object} obj Document to check
@ -653,21 +670,29 @@ function matchQueryPart (obj, queryKey, queryValue) {
var objValue = getDotValue(obj, queryKey) var objValue = getDotValue(obj, queryKey)
, i, keys, firstChars, dollarFirstChars; , i, keys, firstChars, dollarFirstChars;
keys = Object.keys(queryValue);
firstChars = _.map(keys, function (item) { return item[0]; });
dollarFirstChars = _.filter(firstChars, function (c) { return c === '$'; });
// Check if the object value is an array treat it as an array of { obj, query } // Check if the object value is an array treat it as an array of { obj, query }
// Where there needs to be at least one match // Where there needs to be at least one match
if (util.isArray(objValue)) { if (util.isArray(objValue)) {
if (dollarFirstChars.length > 0) {
if (!queryOperators[keys[0]]) { throw "Unknown query operator " + keys[i]; }
if (!queryOperators[keys[0]](objValue, queryValue[keys[0]])) { return false; }
return true;
} else {
for (i = 0; i < objValue.length; i += 1) { for (i = 0; i < objValue.length; i += 1) {
if (matchQueryPart({ k: objValue[i] }, 'k', queryValue)) { return true; } // k here could be any string if (matchQueryPart({ k: objValue[i] }, 'k', queryValue)) { return true; } // k here could be any string
} }
return false; return false;
} }
}
// queryValue is an actual object. Determine whether it contains comparison operators // queryValue is an actual object. Determine whether it contains comparison operators
// or only normal fields. Mixed objects are not allowed // or only normal fields. Mixed objects are not allowed
if (queryValue !== null && typeof queryValue === 'object' && !util.isRegExp(queryValue)) { if (queryValue !== null && typeof queryValue === 'object' && !util.isRegExp(queryValue)) {
keys = Object.keys(queryValue);
firstChars = _.map(keys, function (item) { return item[0]; });
dollarFirstChars = _.filter(firstChars, function (c) { return c === '$'; });
if (dollarFirstChars.length !== 0 && dollarFirstChars.length !== firstChars.length) { if (dollarFirstChars.length !== 0 && dollarFirstChars.length !== firstChars.length) {
throw "You cannot mix operators and normal fields"; throw "You cannot mix operators and normal fields";

Loading…
Cancel
Save