How we can query to firebase from angularfire to match two conditions. i wanted to search below two conditions as AND match
A Firebase query can currently only contain one orderBy...
call. They can also only query properties that are one level below the nodes being returned.
So you cannot implement your requirements in the way you probably initially hoped:
// THIS IS AN EXAMPLE THAT WILL NOT WORK
ref.child('color')
.orderByChild('color').equalTo('red')
.orderByChild('color/categories').equalTo('hex');
In some cases, you can get away with introducing a top-level property that combines the values you want to filter on. So let's say your color can only be in one category. You could then add an additional colorcategory
property:
{ "color" : { "-UqPNlZ8ddgdGMFSsD" : { "color" : "red", "colorcategory": "redhex", "categories" : { "hex" : { "subcategory" : [ "#111", "#333" ] } }, "status" : "ok" }, "-U9P4pBpYiId3ID64K" : { "color" : "blue", "colorcategory" : "bluehex", "categories" : { "hex" : { "subcategory" : [ "#ffffd", "#eee" ] } }, "status" : "ok" }, "-U9UgOdffZdfdbSydF" : { "color" : "green", "colorcategory" : "greenhex", "categories" : { "hex" : { "subcategory" : [ "#333", "#555" ] } }, "status" : "ok" } }
And filter on that:
ref.child('color')
.orderByChild('colorcategory').equalTo('redhex')
This will work when you have two single-value properties, even when they're on different levels in the JSON structure, since you're normalizing those properties and level into a single value on the right level.
But since your categories are multi-value, this approach also won't work. The only approach that I can think of is that you create a so-called secondary index on your data.
An index in a NoSQL database is a data structure, much like a multi-column index in a relational database, that just exists for your queries. In this case, since you want to query on the combination of color and category, I'd expect an index color_category
or maybe even color_category_subcategory
.
color_category_subcategory:
"red_hex_111": "-UqPNlZ8ddgdGMFSsD"
"red_hex_333": "-UqPNlZ8ddgdGMFSsD"
"blue_hex_ffffd": "-U9P4pBpYiId3ID64K"
"blue_hex_eee": "-U9P4pBpYiId3ID64K"
"green_hex_333": "-U9UgOdffZdfdbSydF"
"green_hex_555": "-U9UgOdffZdfdbSydF"
You will have to create and maintain this index from your own code , either in the client-side application or by running a server-side process that creates it. But once you have the index in place, you can query it:
ref.child('color_category_subcategory')
.orderByKey().equalTo('red_hex_333')
.on('value', function(snapshot) {...
Or by range:
ref.child('color_category_subcategory')
.orderByKey().startAt('blue_hex').endAt('blue_hex~')
.on('value', function(snapshot) {...
The ~
above is not a special operator, but just a character that happens to fall after all other characters in an ASCII sequence. So filtering ['blue_hex', 'blue_hex~']
will give all blue hexes.