I have docs analogous to this:
{_id: 1, values : [2,3,4] }
{_id: 2, values: [4] }
{_id: 3, values : [3,4,5,6,7,8,9,10,11] }
in which each doc has an array. I need a query that only returns the doc if EACH element of its array match the desired criteria (rather than if ANY element matches).
Eg. something like (but not)
{ ‘values’ : { ‘$gt’ : 1, ‘$lt’: 5} })
which would successfully return the first two but not the third doc, as not all
elements of the third doc’s array ‘values’ match the criteria.
Apparently mongodb uses an implicit OR in queries on arrays, whereas I need AND.
I guess I could manually index each element, eg.:
collection.find({values.0: {$gt:1,$lt:5}, values.1:{$gt:1,$lt:5}, … values.n:{$gt:1,$lt:5}}) but this is a pain with my highly dynamic arrays.
Is there a better way?
Note: I asked this over at mongodb-user but being new to mongodb generated confusion with $all operator. Here I am concerned about the doc array, not a query array. Also, in this numeric case I realize one might write a query that negates the range desired, but in general I won’t be able to write the negation.
I don’t think there’s any way to do this yet, apart from manually iterating through your documents and checking each value in the array. That’s going to be quite slow because it has to execute JavaScript on each document, and can’t take advantage of any index over
col.values.Even a $where JavaScript expression query doesn’t seem work here because, possibly because the query contains a callback and is too complex:Edit: For some queries, including this one, the JavaScript $where expression needs a return statement, so this works fine: