Fosome / garb

A Ruby wrapper for the Google Analytics API
http://www.viget.com/extend/
654 stars 89 forks source link

AND/OR filtering is confusing #99

Closed dhruvbansal closed 13 years ago

dhruvbansal commented 13 years ago

I want to construct a query that uses a filter of the form

(var1 op1 val1) AND ((var2 op2 val2) OR (var3 op3 val3))

I know this is this is possible in GA and I'm wondering how to express it using Garb.

I've tried

MyMetric.results(:filters => {:var1.contains => 'val1', :var2.contains => 'val2' , :var3.contains => 'val3'})
MyMetric.results(:filters => [{:var1.contains => 'val1'}, {:var2.contains => 'val2' }, {:var3.contains => 'val3'}])
MyMetric.results(:filters => [{:var1.contains => 'val1'}, [{:var2.contains => 'val2' }, {:var3.contains => 'val3'}]])

but none worked. Digging in I see that Garb::Model#results calls Garb::Model#parse_filters which really only passes one set of filters to the newly created instance of Garb::FilterParameters. With this setup it seems that the only sorts of queries that you can do using Garb::Model#results are concatenative AND queries.

FilterParameters does have the ability to construct OR clauses but only at the absolute top level of the filter expression. Or so I'm lead to believe from Garb::FilterParameters#to_params.

All of this has been pretty confusing to suss out as well. Using Ruby data structures to represent complex filters is a common pattern and one that I like using. But when dealing with complex, nested AND/OR expressions it can get pretty confusing. Not suggesting a different implementation here, just pointing out that I'm stymied by the current one.

dhruvbansal commented 13 years ago

BTW I'm using Ruby 1.8.7, Garb 0.9.1.

tpitale commented 13 years ago

I completely agree. Every ruby ORM that I have ever used has failed to solve this elegantly.

I've been working on a branch called filtering that removes all of the half-working cruft, and goes down the path of named filters (ala AR named scopes). While incomplete it does offer some hope for a better future, when I have the time to finish it.

I will try to look tomorrow, and let you know if there is anything else I can do.

tpitale commented 13 years ago

Having re-read, this one case is not currently possible because a Hash is used to indicate AND, and since you can't put an Array (used for OR) into a hash without a key, it isn't supported.

I could ignore the key in the case where a value is in a Array in the key/value pair. But then the keys would simply exist to take up space.

I think the eventual filtering interface will be a much better place to solve this.

In the meantime, I'm adding the ability to support the last syntax example you gave, even though it will not create the filter query you're looking for.

I apologize for the inconvenience, and I hope I can solve this problem for real, soon.