Query Best Practice on child nodes

1,352 views
Skip to first unread message

visdyn

unread,
Feb 6, 2015, 10:55:21 AM2/6/15
to fireba...@googlegroups.com
Looking for advice on best practices when query'ing (or options) when looking for data within a child node.

Scenario: A car lot with cars. In FB we store the car info and some specs about that car.

Lot
parkingSpace0Key
make: Chevy
model: Camaro
specs
color:blue
miles:10000
parkingSpace1Key
make: Ford
model: Mustang
Specs
color:green
miles:12000
parkingSpace2Key
make: Dodge
model: Charger
Specs
color:green
miles:14000



assume that parkingSpace0Key will always have a Chevy Camaro parked in that space but the specs may change (color, miles, sunroof, engine size, etc) so that node will be dynamic and can be a vary'ing list (so we store it in a child node)

Suppose we want to print out all green cars.

in iOS one option is to read in the entire lot node, and iterate over the read in cars and as we come across a green one, print it out.

    [lotRef observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
       
for (FDataSnapshot* child in snapshot.children) {
           
NSDictionary *dict = child.value;
           
NSDictionary *specs = [dict valueForKey:@"specs"];
           
NSString *color = [specs valueForKey:@"color"];
           
if ( [color isEqualToString:@"green"] ) {
               
NSLog(@"The car in space %@ is green", child.key);
           
}
       
}
   
}];


Query option?

We can query on items immediately beneath the parkingSpace node, in this case looking for Chevy

    FQuery *orderedByQuery = [lotRef queryOrderedByChild:@"make"];
   
FQuery *emailQuery = [orderedByQuery queryEqualToValue:@"Chevy"];
   
[emailQuery observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
       
NSLog(@"%@",snapshot.value);
   
}];


Is there a way to query on child nodes to query for green cars?

Is this a situation where flattening the data is the better option?

What are the performance issues with reading in a bunch of data* and iterating over it  vs   some kind of sub-query returning only the data we are interested in?

*lot could be 0-100 cars, 100-1000 cars, or 1000+ cars


Kato Richardson

unread,
Feb 9, 2015, 2:39:27 PM2/9/15
to fireba...@googlegroups.com
Thanks for sharing your questions. Looks like you've fallen into a fairly common scenario. [1] [2] [3].

The solutions, as outlined in the links above, touch on a few key principles:
  • Flatten data to simplify searches
  • Don't nest components without reason
  • Use indices for more dynamic search patterns
  • Implement BigQuery, ElasticSearch, et al (see Flashlight) for advanced querying and fuzzy matching
In this case, assuming the use case is actually this simple, you might just flatten the "specs" node onto its parent for easy searches. It may also be that, if it's more complex than this, the specs actually belong in their own path.

Alternately, depending on the number of spaces in a given Lot and the usage pattern, it may be entirely superfluous to try and force this search server-side, and simpler to just grab the spaces and filter client-side. Without a careful examination of the use case, and an understanding of how often we'll be searching by color vs listing or browsing the results, it's hard to designate which answer will best serve your needs--you can probably intuit that fairly quickly.

I hope that helps!

Cheers,
Kato
Reply all
Reply to author
Forward
0 new messages