Getting query results with Legato gem - ruby-on-rails

Trying to get query results from Google Analytics using Legato gem (following a previous recommendation I go there + some research). Seems to be simple to define my query, however I fail to understand how to actually get the results. Reading the readme shows how to build some "building blocks", but I fail to get an object where I can read the results from.
Maybe I missed something, and the query results should be written directly to the model (DB), which is not what I want (I wanted to go over them first). Maybe that's the reason I'm not seeing anything.
So can someone please share an example how to read the results? For example, just print the pageviews to the screen.
Thanks

So here's the way I've found to use it:
You create a class that defines the "model" of your query (and like Active-Model returning relations, you can also concatenate here). In this example:
The model/query check for pageviews & unique-pageviews within the ga:pagePathLevel1 dimension.
There is an optional filter you can use, looking for 'index' within the pagePathLevel1 (and as you can see, you can chose to use it or not, add more filters, concatenate them, etc.
Also note that the filter & result just return a "query" (just like ActiveModel::Relation), where the execution is done by invoking something on it, like 'each' or 'to_a', etc.
class Pageviews
extend Legato::Model
metrics :pageviews, :uniquePageviews
dimensions :pagePathLevel1
filter(:by_index_in_path_level_1) {|page_path_level1| contains(:pagePathLevel1, 'index')}
def self.query(profile, start_date, end_date)
Pageviews.results(profile,
:start_date => start_date,
:end_date => end_date
)
# Just for reference, sorting descending by pageviews is done by: :sort => '-pageviews'
end
def self.query_index(profile, start_date, end_date)
Pageviews.by_index_in_path_level_1.results(profile,
:start_date => start_date,
:end_date => end_date
)
end
end
Once this is ready, you can do something like:
Pageviews.query(profile, start_date, end_date).each do |result|
# Just print the pageviews & unique-pageviews, for example
puts result.try(:pageviews)
puts result.try(:uniquePageviews)
end
Lastly, I recommand that you first explore with Google Analytics Query Explorer.
I hope you can find this example helpful

Related

How do I get the search to use the attr_accessor?

Ok so i have a date field that i need to search on, but i need to search on it by day like in a mysql query
search_conditions << ["DAY(open_date) != ?", event.thursday.day] if options[:thur].blank?
and i need to do this condition with Thinking Sphinx so i tried this
attr_accessor :event_day
def event_day
self.start_date.day
end
#thinking sphinx configurations for the event search
define_index do
indexes event_day
...
...
and in the search i tried this
search_string = "#event_day -#{event.thursday.day}" unless options[:thur].blank?
but i keep getting this error
index event_core: query error: no field 'event_day' found in schema
Any way to make this work
You can't use a ruby attribute in an SQL query. Rails isn't that clever.
You need to write SQL that replicates that function, or filter the results of a query through it, e.g.
#my_query.where(:a => "b").select { |rec| rec.some_method == "some value" }
As Michael's pointed out, Ruby attributes aren't accessible by Sphinx - it talks directly to your database.
So, either you can create a column that holds the event day value, and reference that via Sphinx, or you can create a field that uses a SQL function (which could vary, depending on MySQL or PostgreSQL) that extracts the day from the start_date column - not particularly complex. It'd probably end up looking like this:
indexes "GET_DAY_FROM_DATE(start_date)", :as => :event_day

Index a boolean field as a string in sphinx

I have a Ruby on Rails site that uses thinking sphinx for searching a postgres database.
One of the fields in a table I am searching on is a boolean.
I'd like to be able to match on that boolean when a certain keyword is used in the search query.
To fully explain with an example:
My site is for people who develop their own black and white film.
I have a recipe table where people describe how they develop a film. That table has a boolean column called "stand_developed" (a method of developing film).
I'd like to return results where that field is true when the user searches for the word "stand".
I've been through the sphinx docs and not really found if it's possible.
I guess I could hack something inside my controller method by parsing the query terms and adding a condition but is there a cleaner way of doing it?
This is what I've done as far as searching on boolean fields using ThinkingSphinx. Pass stand_developed as a URL parameter along with your query_string in the following ways:
URL for a general query without search on stand_developed will be http://yoursite.com/search?q=your_query_string
URL for query with stand_developed == TRUE will be http://yoursite.com/search?q=your_query_string&stand_developed=1
URL for query with stand_developed == FALSE will be http://yoursite.com/search?q=your_query_string&stand_developed=0
Then, in your controller, you would do this:
if params[:stand_developed] && params[:stand_developed].to_i == 1
# perform query search with stand_developed == true
#search_results = YourModel.search(params[:q], :with => {:stand_developed => true})
elsif params[:stand_developed] && params[:stand_developed].to_i == 0
# perform query search with stand_developed == false
#search_results = YourModel.search(params[:q], :with => {:stand_developed => false})
else
# perform general query search
#search_results = YourModel.search(params[:q])
end
You could have just tested if params[:search] included the text 'stand' then done the searching from there. You don't need an extra column in your table, that's just overhead that's not needed.
if params[:search].downcase.include?('stand')
Model.search params[:search], :with => {:stand_developed => true}
else
Model.search params[:search]
end
I've come up with a solution to this now.
I tried the "hack" I mentioned in my question - parsing the word "stand" and searching for it explicitly (a variation on the answer from Paul Davis) but it didn't work very well.
I didn't explain this in my question (didn't realise the full implications at the time I asked) but I need it to also match if the user used the word "stand" in their recipe description too.
So, I tried to get sphinx to add a condition along the lines of "if stand_developed is true or notes contains 'stand'" but I couldn't seem to find the right syntax for that.
It also had to deal with any other search text too.
In the end I added an extra column to my recipe table called "search_tags" and I add the word "stand" into it if the user selects "stand_developed" when adding a recipe.
I then get Sphinx to index that field as well as my other fields and it all works perfectly.

How do I create a 'Most Recently Popular' bar for content in Ruby on Rails?

I'm a noob so please forgive if this is an easy question but I'm trying to create a 'Most Recently Popular' output for specific content on a rails project.
Right now the object I am pulling from has an attribute revision.background_title. I want to calculate popularity by finding the number of specific background_title's added over the past seven days then put them in order. For example if there are 4 background_title's named 'awesomecontent' then that would be above one that has 1 background_title named 'less awesome content'
This pulls all of them:
#revisions = Revision.find(:all, :order => "created_at desc")
Thanks.
You can use the basic ActiveRecord find method to do this. The code would end up looking something like this:
#revisions = Revision.all(
:select => "background_title, count(*) count", # Return title and count
:group => 'background_title', # Group by the title
:order => '2 desc' # Order by the count descending
)
To see the output, you could then do something like this:
#revisions.each do |revision|
puts "Revision #{revision.background_title} appears #{revision.count} times"
end
giving
Revision z appears 10 times
Revision a appears 3 times
Revision b appears 2 times
Another option would be to take a look at ActiveRecord::Calculations:
http://api.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html
Calculations supports a count method that also supports the group option. However, going this route will give you back a hash containing the background_title as the key and the count as the value. Personally, find the first method more useful.

rails - activerecord ... grab first result

I want to grab the most recent entry from a table. If I was just using sql, you could do
Select top 1 * from table ORDER BY EntryDate DESC
I'd like to know if there is a good active record way of doing this.
I could do something like:
table.find(:order => 'EntryDate DESC').first
But it seems like that would grab the entire result set, and then use ruby to select the first result. I'd like ActiveRecord to create sql that only brings across one result.
You need something like:
Model.first(:order => 'EntryDate DESC')
which is shorthand for
Model.find(:first, :order => 'EntryDate DESC')
Take a look at the documentation for first and find for details.
The Rails documentation seems to be pretty subjective in this instance. Note that .first is the same as find(:first, blah...)
From:http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002263
"Find first - This will return the first record matched by the options used. These options can either be specific conditions or merely an order. If no record can be matched, nil is returned. Use Model.find(:first, *args) or its shortcut Model.first(*args)."
Digging into the ActiveRecord code, at line 1533 of base.rb (as of 9/5/2009), we find:
def find_initial(options)
options.update(:limit => 1)
find_every(options).first
end
This calls find_every which has the following definition:
def find_every(options)
include_associations = merge_includes(scope(:find, :include), options[:include])
if include_associations.any? && references_eager_loaded_tables?(options)
records = find_with_associations(options)
else
records = find_by_sql(construct_finder_sql(options))
if include_associations.any?
preload_associations(records, include_associations)
end
end
records.each { |record| record.readonly! } if options[:readonly]
records
end
Since it's doing a records.each, I'm not sure if the :limit is just limiting how many records it's returning after the query is run, but it sure looks that way (without digging any further on my own). Seems you should probably just use raw SQL if you're worried about the performance hit on this.
Could just use find_by_sql http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002267
table.find_by_sql "Select top 1 * from table ORDER BY EntryDate DESC"

Filtering Sphinx search results by date range

I have Widget.title, Widget.publish_ at, and Widget.unpublish_ at. It's a rails app with thinking_sphinx running, indexing once a night. I want to find all Widgets that have 'foo' in the title, and are published (publish _at < Time.now, unpublish _at > Time.now).
To get pagination to work properly, I really want to do this in a sphinx query. I have
'has :publish_at, :unpublish_at' to get the attributes, but what's the syntax for 'Widget.search("foo #publish_ at > #{Time.now}",:match _mode=>:extended'? Is this even possible?
Yep, easily possible, just make sure you're covering the times in your indexes:
class Widget < ActiveRecord::Base
define_index do
indexes title
has publish_at
has unpublish_at
...
end
To pull it based purely off the dates, a small amount of trickery is required due to sphinx requiring a bounded range (x..y as opposed to x>=y). The use of min/max value is very inelegant, but I'm not aware of a good way around it at the moment.
min_time = Time.now.advance(:years => -10)
max_time = Time.now.advance(:years => 10)
title = "foo"
Widget.search title, :with => {:publish_at => min_time..Time.now, :unpublish_at => Time.now..max_time}
I haven't used sphinx with rails yet.
But this is possible by the Sphinx API.
What you need to do is to set a datetime attribute at your sphinx.conf.
And don't forget to use UNIX_TIMESTAMP(publish_at), UNIX_TIMESTAMP(unpublish_at) at your index select.

Resources