mongodb - Check last element in array matches a condition -
i have array of numbers in mongodb documents , need check if last number in array meets conditions.
my documents stored this:
{ name: string, data: { dates: array, numbers: array } }
and need check if last number in numbers
"lies between" 2 other numbers.
any suggestions on how appreciated.
right effficient way have of doing using javascript evaluation of $where
can find value of last array element , test programatically.
with sample documents:
{ "a": [1,2,3] }, { "a": [1,2,4] }, { "a": [1,2,5] }
and query:
db.collection.find(function() { var = this.a.pop(); return ( > 2 ) & ( < 5 ) })
or presented $where
string evaluation:
model.find( { "$where": "var = this.a.pop(); return ( > 2 ) && ( < 5 )" }, function(err,results) { // handling here } );
which simple way , not have "overhead" such $unwind
in aggregation framework created to "denormalize" , process arrays. not efficient there.
in "future" however, will be. available in development releases, there $slice
operator aggregation framework. operator allow easy access "last" array element testing.
since aggregation framework operators in "native code" aand not javascript interpreted, single pipeline stage becomes more efficient javascript form. though listing looks longer in submission:
db.collection.aggregate([ { "$redact": { "$cond": { "if": { "$anyelementtrue": { "$map": { "input": { "$slice": ["$a",-1] }, "as": "el", "in":{ "$and": [ { "$gt": [ "$$el", 2 ] }, { "$lt": [ "$$el", 5 ] } ] } } } }, "then": "$$keep", "else": "$$prune" } }} ])
the $redact
operator exists used "logically filter" comparison expression here. based on true/false
match conditions either "keeps" or "prunes" document results repectively.
the $slice
operator in it's aggregagtion framework form still untimately return array, albeit single element array in case. why $map
used "transform" each element true/false
condition , $anyelementtrue
operator reduces "array" singular reponse repected $cond
.
so when released, be efficient way this. until then, stick javascript presently fastest way to evaluation.
both query forms return first 2 documents of sample here:
{ "a": [1,2,3] }, { "a": [1,2,4] }
Comments
Post a Comment