Full-text search on Heroku using pg_search gem - ruby-on-rails

I've implemented full-text search using pg_search gem for my Rails application
My migration to create index looks like
execute(<<-'eosql'.strip)
CREATE index mytable_fts_idx
ON mytable
USING gin(
(setweight(to_tsvector('english', coalesce("mytable"."name", '')), 'A') ||
' ' ||
setweight(to_tsvector('english', coalesce("mytable"."description",'')), 'B')
)
)
eosql
And my controller code looks like
pg_search_scope :full_text_search,
:against => [
:name, :description],
:using => {
:tsearch => {
:prefix => true,
:dictionary => "english",
:any_word => true
}
}
which works totally fine locally on Postgres 9.0.4. However, when I deploy the same to heroku and search for a sample query 'test', it throws up an error
PGError: ERROR: syntax error in tsquery: "' test ':*"
SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "mytable" WHERE (((to_tsvector('english', coalesce("mytable"."name", '')) || to_tsvector('english', coalesce("mytable"."description", ''))) ## (to_tsquery('english', ''' ' || 'test' || ' ''' || ':*')))) LIMIT 12 OFFSET 0) subquery_for_count ):
Any suggestions on where I'm wrong and what I should be looking at to fix this error? Thanks.

I'm the main developer of pg_search. Sorry that you ran into that problem! Right now there is a pg_search bug when using :prefix searches against PostgreSQL 8.3 (the default for Heroku).
https://github.com/Casecommons/pg_search/issues/10
It's my top priority right now. I'm still figuring out the best way to get the test suite to run against both 8.x and 9.x.
Update: Unfortunately, :prefix searches don't work against PostgreSQL 8.3 at all. The functionality was introduced in 8.4. I've released pg_search 0.3.3 which improves the error message. Hopefully Heroku will upgrade to 9.0 across the board soon. I believe they want to do so, but they obviously can't just upgrade everyone wholesale without warning.

Related

NoMethodError - undefined method `where_values' | Upgraded from rails 4.2 to 5.0.1

I have recently upgraded my rails app from 4.2.8 to 5.0.1 with ruby 2.4.5
Facing this error
NoMethodError - undefined method `where_values' for
Query:
PlacementActivityStep.where(query_values_hash[:query_string], query_values_hash[:values])
.where_values.select{|x| x.present?}
How do I achieve the same query in rails 5.0.1 using where_clause as where_values has been removed from the new rails version??
Reference: Ruby on Rails where_values method
Following is tested in Rails 5.2.2
First, where_values was not intended for public use, see https://bugs.ruby-lang.org/issues/12962
And to get the same behavior you must do some hacks.
I don't know what you will use the generated arel code for, I prefer to make the condition directly with arel if it's a complicated condition. And you will lose some automatic type detection.
Consider this (bad example but only to show the difference):
# model Foo have column 'bar' that is sql type string
Foo.where('bar = :one OR bar = :two', one: 55, two: nil ).to_sql
=> "SELECT `foos`.* FROM `foos` WHERE (firstname = 55 OR firstname = NULL)"
# bad, the last should be "firstname IS NULL"
# use Rails "magic"
Foo.where(bar: [ 55, nil ]).to_sql
=> "SELECT `foos`.* FROM `foos` WHERE (`foos`.`firstname` = '55' OR `foos`.`firstname` IS NULL)"
# "`firstname` IS NULL" as it should be (and '55' is a string)
# if it is the arel you want, you can use it directly
fo_a = Foo.arel_table
fo_a[:bar].eq_any([ 55, nil ]).to_sql
=> "(`foos`.`firstname` = '55' OR `foos`.`firstname` IS NULL)"
# that is the same as if you where using this in Rails 4:
Foo.where(bar: [ 55, nil ]).where_values.first.to_sql
# even if you use a hackish way you will not get the same result
Foo.where(bar: [ 55, nil ]).where_clause.send(:predicates).first.to_sql
=> "(`foos`.`firstname` = ? OR `foos`.`firstname` IS NULL)"
# '55' is gone (it's a "bind value")

Error after upgrade from Rails 4.0 to Rails 4.2 in activerecord relation

I have upgraded from Rails 4 to Rails 4.2 following the official documentation.
By the way I have a bug to fix.
In my search controller I have:
#contents = Content.published.search_by_text(#query)
Content Load (248.7ms) SELECT "contents".*, ((ts_rank(("contents"."tsv"), (to_tsquery('italian', ''' ' || 'ces' || ' ''')), 0))) AS pg_search_rank FROM "contents" WHERE "contents"."state" = $1 AND (published_at <= '2015-04-07 16:38:38.000591') AND ((("contents"."tsv") ## (to_tsquery('italian', ''' ' || 'ces' || ' ''')))) ORDER BY published_at DESC, pg_search_rank DESC, "contents"."id" ASC [["state", "published"]]
=> []
#contents.count
PG::SyntaxError: ERROR: syntax error at or near "AS"
In Rails 4.0 it returns '0'. The issue of course is related to #comments.
#contents.class
=> Content::ActiveRecord_Relation
I add to_a and now it works.
#contents.to_a.count
=> 0
I want to understand why I need to convert to array the result of an active record query. What is changed in Rails 4.2?

Thinking Sphinx and Norwegian characters (æ, ø, å)

I've set up Thinking Sphinx for wildcard searches, but I'm having trouble searching for words containing Norwegian characters, as the automatic starring seems to mess up the query. For instance, my search for "ål" will end up with:
Sphinx Query (2.8ms) å*l*
Sphinx Found 0 results
If I manually enter the stars in the search term, "*ål*", the expected results are returned:
Sphinx Query (3.7ms) *ål*
Sphinx Found 8 results
It seems somehow the å (as well as æ, ø) gets misinterpreted when automatically adding the stars.
Anyone here familiar with this problem?
My config/sphinx.yml looks as follows:
development:
enable_star: 1
min_infix_len: 2
charset_table: "U+FF10..U+FF19->0..9, U+FF21..U+FF3A->a..z, U+FF41..U+FF5A->a..z, 0..9, A..Z->a..z, a..z,
U+C5->U+E5, U+E5, U+D8->U+F8, U+F8, U+C6->U+E6, U+E6,
U+C4->U+E4, U+E4, U+D6->U+F6, U+F6"
And a couple of examples of searches performed in the console:
ruby-1.9.2-p290 :014 > ThinkingSphinx.search("ål", :star => true).count
=> 0
ruby-1.9.2-p290 :015 > ThinkingSphinx.search("*ål*", :star => true).count
=> 8
This has been fixed in recent commits - for the moment, you'll need to grab it via the repo:
gem 'thinking-sphinx',
:git => 'git://github.com/freelancing-god/thinking-sphinx.git'

PostgreSQL and Heroku, find and group

I'm trying to get an app to run on Heroku properly. (Heroku uses the postgreSQL database, yeh?)
In development, I'm using sqlite, and this is my code in a controller =>
#productsort = Products.find(:all,
:select => 'count(*) count, color',
:group => 'color',
:order => 'count DESC',
:conditions => 'size = "Small"')
As you can see, I'm trying to group products by their colors, and order them by greatest amount to least.
Also, the products must be "Small". (the conditions)
In SQL, it works fine.
But not in PostgreSQL (heroku).
This is from running "heroku log"
2011-06-20T18:20:33+00:00 app[web.1]: ActiveRecord::StatementInvalid (PGError: ERROR: column "Small" does not exist
2011-06-20T18:20:33+00:00 app[web.1]: LINE 1: ...ducts".* FROM "products" WHERE (size = "Smal...
Hm... I've searched around and I couldn't find anything similar to what I have.
All help would be appreicated. Thank you
You need to be using single quotes around your strings in the conditions (double quotes may work with sqlite, but they definitely don't with PostgreSQL).
So replace your conditions with this:
:conditions => "size = 'Small'"
It will still work in SQLite too.

Rails Location based search not working on Heroku

Recently I deployed my application on Heroku. I'm using Geokit to search events, based on user's location.
#events = Event.all(:origin => [#location.lat, #location.lng], :within => 5, :conditions => ["end_date >= ?", Date.today], :select => "id, created_at, user_id, location, description, permalink, title", :order => "created_at DESC")
The above statement is working fine in my local system with mysql database.
But I'm getting error while executing same stmt on Heroku. Please check the below error I'm facing on Heroku.
ActiveRecord::StatementInvalid (PGError: ERROR: function radians(character varying) does not exist
2011-03-20T00:52:23-07:00 app[web.1]: LINE 2: ...,COS(0.303256183987648)*COS(1.36963671754269)*COS(RADIANS(fr...
2011-03-20T00:52:23-07:00 app[web.1]: ^
2011-03-20T00:52:23-07:00 app[web.1]: HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Any help would be greatly appreciated.
Thanks,
Kalyan.
As a heads-up, Heroku uses Postgres as the only SQL database backend: http://devcenter.heroku.com/articles/database
Therefore, your problem is related to these two Q&A:
Why does Postgresql fail with Geokit like this?
Rails: Converting from MySQL to PostGres breaks Geokit Distance Calculations?
In your case, you should add a database migration and change "lat" and "lng" in your location model from "string" (or "text") to "float", and then Geokit should work fine with Postgres and Heroku respectively.

Resources