Multiple conditions in nested objects in an array
risinek opened this issue · 3 comments
Lets assume the JSON object {cars: [{brand: 'porsche',hp:450},{brand: 'bmw',hp:250},{brand: 'lada',hp:10}]}
And now I want to check if there is a BMW with more then 300hp.
If I run the query {cars.brand: 'bmw', cars.hp: {gt: 300}
I expect to get false
as there is no BMW with over 300 hp, but I actually get true
. I assume it's because it first matches the object {brand: 'bmw',hp:250}
by the brand
and then {brand: 'porsche',hp:450}
by the condition on hp
field -> hence both conditions are met -> true
Is it possible to search by multiple conditions for nested object in current implementation?
It should work, I am surprised it does not. If you feel like stepping through it to figure out why and then propose a PR, that would be good.
So I checked the code and it confirms my assumption. Lets assume the input query and recapitulate the scenario
{cars.brand: 'bmw', cars.hp: 450}
- Expected result: false
- there is no object satisfying both conditions.
- Actual result: true
{brand: 'porsche',hp:450}
matcheshp:450
{brand: 'bmw',hp:250}
matchesbrand: 'bmw'
The reason for this "unexpected" behavior lies in the way the search terms are resolved. Every search term is resolved in isolation.
Line 136 in f612eca
My proposal is to allow queries like this
{"cars": {brand: 'bmw', hp: 450}}
Then in the singleMatch()
the returned object for cars
property would be array of objects
[{brand: 'porsche',hp:450},{brand: 'bmw',hp:250},{brand: 'lada',hp:10}]
which is then recursively resolved in this block
Lines 78 to 85 in f612eca
which will resolve every object again by calling
singleMatch()
for each object.Now the problem is, that
{brand: 'porsche',hp:450}
hence typeof object
and hence satisfying this if blockLines 86 to 88 in f612eca
Here it would be possible to call
matchObject()
on this object and let it resolve.
I'm writing you this as an headsup while coding the proposed solution. If you can see any obstacles, please let me know.
Makes sense. Given the doc, it should have done that already, I think.