Nested matching works for array fields

pull/2/head
Louis Chatriot 12 years ago
parent 14e9484844
commit 27352bc410
  1. 40
      lib/model.js
  2. 16
      test/model.test.js

@ -296,6 +296,22 @@ matcherFunctions.$eq = function (objValue, value) {
};
/**
* Match any of the subconditions
*/
matcherFunctions.$or = function (obj, query) {
var i;
if (!util.isArray(query)) { throw "$or operator used without an array"; }
for (i = 0; i < query.length; i += 1) {
if (match(obj, query[i])) { return true; }
}
return false;
};
/**
* Tell if a given document matches a query
* @param {Object} obj Document to check
@ -323,16 +339,24 @@ function matchQueryKey (obj, query, queryKey) {
, i
;
if (util.isArray(objValue)) {
for (i = 0; i < objValue.length; i += 1) {
if (matcherFunctions.$eq(objValue[i], queryValue)) { return true; }
}
return false;
if (queryKey[0] === '$') {
// We apply an operator like $or, $and
if (!matcherFunctions[queryKey]) { throw "Unknown query operator " + queryKey; }
return matcherFunctions[queryKey](obj, queryValue);
} else {
if (!matcherFunctions.$eq(objValue, queryValue)) { return false; }
}
// Normal field matching
if (util.isArray(objValue)) {
for (i = 0; i < objValue.length; i += 1) {
if (matcherFunctions.$eq(objValue[i], queryValue)) { return true; }
}
return false;
} else {
if (!matcherFunctions.$eq(objValue, queryValue)) { return false; }
}
return true;
return true;
}
}

@ -414,11 +414,27 @@ describe('Model', function () {
it('For field array, a match means a match on at least one element', function () {
model.match({ tags: ['node', 'js', 'db'] }, { tags: 'python' }).should.equal(false);
model.match({ tags: ['node', 'js', 'db'] }, { tagss: 'js' }).should.equal(false);
model.match({ tags: ['node', 'js', 'db'] }, { tags: 'js' }).should.equal(true);
model.match({ tags: ['node', 'js', 'db'] }, { tags: 'js', tags: 'node' }).should.equal(true);
// Mixed matching with array and non array
model.match({ tags: ['node', 'js', 'db'], nedb: true }, { tags: 'js', nedb: true }).should.equal(true);
// Nested matching
model.match({ number: 5, data: { tags: ['node', 'js', 'db'] } }, { "data.tags": 'js' }).should.equal(true);
model.match({ number: 5, data: { tags: ['node', 'js', 'db'] } }, { "data.tags": 'j' }).should.equal(false);
});
});
describe('$or', function () {
it('Any of the subconditions can be used', function () {
model.match({ hello: 'world' }, { $or: [ { hello: 'pluton' }, { hello: 'world' } ] }).should.equal(true);
model.match({ hello: 'pluton' }, { $or: [ { hello: 'pluton' }, { hello: 'world' } ] }).should.equal(true);
model.match({ hello: 'nope' }, { $or: [ { hello: 'pluton' }, { hello: 'world' } ] }).should.equal(false);
});
});

Loading…
Cancel
Save