New operator and extended dot operator document search

pull/2/head
Leandro Ferrari Thomaz 11 years ago
parent d6eeb00d95
commit bbc1ff6eb7
  1. 97
      lib/model.js

@ -573,6 +573,10 @@ comparisonFunctions.$exists = function (value, exists) {
}
};
queryOperators.$size = function (obj, value) {
return (util.isArray(obj) && obj.length == value);
};
/**
* Match any of the subqueries
* @param {Model} obj
@ -619,17 +623,6 @@ 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
* @param {Object} obj Document to check
@ -667,56 +660,62 @@ function match (obj, query) {
* Match an object against a specific { key: value } part of a query
*/
function matchQueryPart (obj, queryKey, queryValue) {
var objValue = getDotValue(obj, queryKey)
, i, keys, firstChars, dollarFirstChars;
var objValue = getDotValue(obj, queryKey)
, i, keys, firstChars, dollarFirstChars;
// 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
if (util.isArray(objValue)) {
// Check if it's a query operator
// TODO REFACTOR!!! keys[0]!!!
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 === '$'; });
// queryValue is an object of this form: { <array>: queryOperator }
if (dollarFirstChars.length > 0 && queryOperators[keys[0]]) {
if (!queryOperators[keys[0]](objValue, queryValue[keys[0]])) { return false; }
return true;
}
}
// Else, process every array value
for (i = 0; i < objValue.length; i += 1) {
if (matchQueryPart({ k: objValue[i] }, 'k', queryValue)) { return true; } // k here could be any string
}
return false;
}
// queryValue is an actual object. Determine whether it contains comparison operators
// or only normal fields. Mixed objects are not allowed
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 === '$'; });
// 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
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) {
if (matchQueryPart({ k: objValue[i] }, 'k', queryValue)) { return true; } // k here could be any string
}
return false;
}
if (dollarFirstChars.length !== 0 && dollarFirstChars.length !== firstChars.length) {
throw "You cannot mix operators and normal fields";
}
// queryValue is an actual object. Determine whether it contains comparison operators
// or only normal fields. Mixed objects are not allowed
if (queryValue !== null && typeof queryValue === 'object' && !util.isRegExp(queryValue)) {
// queryValue is an object of this form: { $comparisonOperator1: value1, ... }
if (dollarFirstChars.length > 0) {
for (i = 0; i < keys.length; i += 1) {
if (!comparisonFunctions[keys[i]]) { throw "Unknown comparison function " + keys[i]; }
if (dollarFirstChars.length !== 0 && dollarFirstChars.length !== firstChars.length) {
throw "You cannot mix operators and normal fields";
}
// queryValue is an object of this form: { $comparisonOperator1: value1, ... }
if (dollarFirstChars.length > 0) {
for (i = 0; i < keys.length; i += 1) {
if (!comparisonFunctions[keys[i]]) { throw "Unknown comparison function " + keys[i]; }
if (!comparisonFunctions[keys[i]](objValue, queryValue[keys[i]])) { return false; }
}
return true;
}
if (!comparisonFunctions[keys[i]](objValue, queryValue[keys[i]])) { return false; }
}
return true;
}
}
// Using regular expressions with basic querying
if (util.isRegExp(queryValue)) { return comparisonFunctions.$regex(objValue, queryValue); }
// Using regular expressions with basic querying
if (util.isRegExp(queryValue)) { return comparisonFunctions.$regex(objValue, queryValue); }
// queryValue is either a native value or a normal object
// Basic matching is possible
if (!areThingsEqual(objValue, queryValue)) { return false; }
// queryValue is either a native value or a normal object
// Basic matching is possible
if (!areThingsEqual(objValue, queryValue)) { return false; }
return true;
return true;
}

Loading…
Cancel
Save