What is wrong with this Sunspot Solr setup? - ruby-on-rails

I am using sunspot to search my local db. After adding the gems, running the generate command, and booting up the solr server I do the following:
class Style < ActiveRecord::Base
attr_accessible :full_name, :brand_name
searchable do
text :full_name
text :brand_name
end
end
Added the above to my Style model and re-indexed (I had already indexed prior to creating this post, which is why I re-indexed to put it here)
funkdified#vizio ~/rails_projects/goodsounds.org $ rake sunspot:solr:reindex
[RailsAdmin] RailsAdmin initialization disabled by default. Pass SKIP_RAILS_ADMIN_INITIALIZER=false if you need it.
*Note: the reindex task will remove your current indexes and start from scratch.
If you have a large dataset, reindexing can take a very long time, possibly weeks.
This is not encouraged if you have anywhere near or over 1 million rows.
Are you sure you want to drop your indexes and completely reindex? (y/n)
y
[#######################################] [14/14] [100.00%] [00:00] [00:00] [53.19/s]
Then I try a search and get nothing
1.9.3p392 :003 > Style.search { fulltext 'Monkey' }.results
SOLR Request (10.4ms) [ path=#<RSolr::Client:0x0000000685ab28> parameters={data: fq=type%3AStyle&q=Monkey&fl=%2A+score&qf=full_name_text+brand_name_text&defType=dismax&start=0&rows=30, method: post, params: {:wt=>:ruby}, query: wt=ruby, headers: {"Content-Type"=>"application/x-www-form-urlencoded; charset=UTF-8"}, path: select, uri: http://localhost:8982/solr/select?wt=ruby, open_timeout: , read_timeout: , retry_503: , retry_after_limit: } ]
=> []
But, wait shouldn't it have worked and picked this up?
Style.first
Style Load (1.3ms) SELECT "styles".* FROM "styles" LIMIT 1
=> #<Style id: 54, brand_name: "Monkey", full_name "Monkey Chicken", created_at: "2013-02-01 23:25:58", updated_at: "2013-02-16 03:02:16">
Here is one more clue. I am seeing "unknown field" for brand_name (setup in Style.rb)

If you change the schema (the "searchable" block) you have to either reindex all models:
rake sunspot:solr:reindex
or reindex that specific model with a given batch size (here 500):
rake sunspot:solr:reindex[500,Style]
as per the Sunspot doco on Github (search "Reindexing Objects").
FYI, to use Style.reindex for non-schema changes, you will have to call Sunspot.commit to save changes.

Related

Renaming field in Mongoid does not update field in class

When I rename a field in Mongoid, it successfully updates the field in MongoDB, but it does not update the field in the ruby code:
class Example
include Mongoid::Document
field :apple, type: String, as: :c_apple
end
Example.all
=> #<Mongoid::Criteria
selector: {}
options: {}
class: Example
embedded: false>
Example.all.rename("apple" => "d_apple")
MOPED: 127.0.0.1:27017 UPDATE database=core collection=examples selector={} update={"$rename"=>{"apple"=>"d_apple"}} flags=[:multi]
COMMAND database=core command={:getlasterror=>1, :w=>1} runtime: 1.2460ms
=> {"connectionId"=>2, "updatedExisting"=>false, "n"=>0, "syncMillis"=>0, "writtenTo"=>nil, "err"=>nil, "ok"=>1.0}
e = Example.new
=> #<Example _id: 5bfdbf103ed1492f9a000001, apple(c_apple): nil>
e.d_apple
NoMethodError: undefined method `d_apple' for #<Example _id: 5bfdbf103ed1492f9a000001, apple(c_apple): nil>
Why are the changes in MongoDB not reflected in class definition?
When you run #rename, you interact with MongoDB. The change of document structure is stored in the database. This method does not interact with ruby source code, you need to edit it by yourself.
Btw. I can't recall any ruby/rails method (besides ones in rake tasks and generators) that interacts with the source code stored in files.

Sunspot search result is empty when using rspec testing

The search function works fine in development and Production. But when I run Rspec tests. the result array is always empty
In my search action log, I can see the data has been indexed and fetched correctly:
Parameters: {"utf8"=>"✓", "ga_client_id"=>"", "search"=>"David"}
SOLR Request (3.9ms) [ path=#<RSolr::Client:0x007fb7f9141f00> parameters={data: fq=type%3AToon&sort=created_at_d+asc&q=David&fl=%2A+score&qf=name_text+author_text+toon_typetext+tags_text&defType=dismax&start=0&rows=9, method: post, params: {:wt=>:ruby}, query: wt=ruby, headers: {"Content-Type"=>"application/x-www-form-urlencoded; charset=UTF-8"}, path: select, uri: http://localhost:8981/solr/select?wt=ruby, open_timeout: , read_timeout: , retry_503: , retry_after_limit: } ]
Toon Load (0.4ms) SELECT "toons".* FROM "toons" WHERE "toons"."id" IN (15550, 15551, 15552) AND (state in ('created','flagged'))
In my Controller
#search = Toon.solr_search do
fulltext params[:search]
order_by :created_at, :asc
paginate :page => params[:page], :per_page => 9
end
#toons = #search.results
My rspec test: https://gist.github.com/jianbo/6360486
In testing View
<%= #search.inspect %> This output correctly as follow:
<Sunspot::Search:{:fq=>["type:Toon"], :sort=>"created_at_d asc", :q=>"papabear", :fl=>"* score", :qf=>"name_text author_text toon_type_text tags_text", :defType=>"dismax", :start=>0, :rows=>9}>
<%= #toons.inspect %> is empty array
UPDATE
I just found that if I do no clear the index and the database, and after running the test twice, I was able to search for the result that was in the first run test.
You will want to fire up a Solr instance for the tests. There is a very helpful snippet here that can help: https://github.com/sunspot/sunspot/wiki/RSpec-and-Sunspot#running-sunspot-during-testing

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'

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.

How Do I Update Nested Mongo Document Attributes in Rails with Mongoid?

(Apologies in advance if this question is short on details, I'll watch the comments and add what I can)
I have a Model with the following:
class Product
include Mongoid::Document
include Mongoid::Timestamps
#...
field :document_template, :type => Document
accepts_nested_attributes_for :document_template
Inside the Document document_template, is the following references_many, which I want to modify. Specifically, I want to change which fonts are referenced:
class Document
include Mongoid::Document
include Mongoid::Timestamps
#...
references_many :fonts, :stored_as => :array, :inverse_of => :documents
What sort of logic and details should I have in my controller and form to get this done? Please comment if you would like me to add some of the zany things I've tried; however, I haven't had any luck with any of them.
Here is a quick showing of the issue using rails console:
# Grab a Product and check how many fonts are in it's document_template
ruby-1.8.7-p302 > prod = Product.find(:first)
=> ...
ruby-1.8.7-p302 > prod._id
=> BSON::ObjectId('4d06af15afb3182bf5000111')
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 9
# Remove a font from the font_ids array
ruby-1.8.7-p302 > prod.document_template.font_ids.pop
=> BSON::ObjectId('...') # This font id was removed from font_ids
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 8
# Save the changes
ruby-1.8.7-p302 > prod.document_template.save!
=> true
ruby-1.8.7-p302 > prod.save!
=> true
# Instantiate a new product object of that same product
ruby-1.8.7-p302 > prod_new = Product.find(:first)
=> ...
# Confirm the _ids are the same
ruby-1.8.7-p302 > prod._id == prod_new._id
=> true
# Check to see if the changes were persisted
ruby-1.8.7-p302 > prod_new.document_template.font_ids.count
=> 9 # If the changes persisted, this should be 8.
# Grrrrr... doesn't look like it. Will the change disappear after a reload too?
ruby-1.8.7-p302 > prod.reload
=> ...
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 9
# ಠ_ಠ ... no dice.
Updating objects using mongo (and not mongoid in rails) works as expected.
Kyle Banker has asked for some logging info, so here it is. Unfortunatly, I couldn't find a better source of logging than the output from rails server, which seems to suggest the update call is never being made. For some context here is some info from the controller:
def update_resource(object, attributes)
update_pricing_scheme(object, attributes)
update_document_template_fonts(object, attributes)
end
def update_document_template_fonts(object, attributes)
document_template = object.document_template
document_template_attributes = attributes[:document_template_attributes]
font_ids = document_template_attributes[:font_ids]
font_ids.delete("") # Removing an empty string that tags along with the font_ids.
font_ids.collect! { |f| BSON::ObjectId(f) } # Mongo want BSON::ObjectId
object.document_template.font_ids.replace font_ids
object.document_template.save!(:validate => false)
object.save!(:validate => false)
end
Here is the output from rails server when the POST is processed:
Started GET "/admin/products/4d091b18afb3180f3d000111" for 127.0.0.1 at Wed Dec 15 13:57:28 -0600 2010
Started POST "/admin/products/4d091b18afb3180f3d000111" for 127.0.0.1 at Wed Dec 15 13:57:49 -0600 2010
Processing by Admin::ProductsController#update as HTML
Parameters: {"commit"=>"Update Product", "authenticity_token"=>"QUW0GZw7nz83joj8ncPTtcuqHpHRtp1liq8fB7/rB5s=", "utf8"=>"✓", "id"=>"4d091b18afb3180f3d000111", "product"=>{"name"=>"Ho Ho Ho Flat Multiple Photo Modern Holiday Card", "document_template_attributes"=>{"id"=>"4d091b18afb3180f3d000112", "font_ids"=>["", "4d091b17afb3180f3d000023"]}, "description"=>"", "pricing_scheme_id"=>"4d091b17afb3180f3d00003b"}}
development['users'].find({:_id=>BSON::ObjectId('4d091b17afb3180f3d00009b')}, {}).limit(-1)
development['products'].find({:_id=>BSON::ObjectId('4d091b18afb3180f3d000111')}, {}).limit(-1)
development['pricing_schemes'].find({:_id=>BSON::ObjectId('4d091b17afb3180f3d00003b')}, {}).limit(-1)
MONGODB development['products'].update({"_id"=>BSON::ObjectId('4d091b18afb3180f3d000111')}, {"$set"=>{"updated_at"=>Wed Dec 15 19:57:50 UTC 2010}})
in Document#set_default_color_scheme: self.color_scheme = #<ColorScheme:0xb52f6f38>
MONGODB development['documents'].update({"_id"=>BSON::ObjectId('4d091b18afb3180f3d000112')}, {"$set"=>{"color_scheme_name"=>"green_charcoal_black", "updated_at"=>Wed Dec 15 19:57:50 UTC 2010}})
Redirected to http://localhost:3000/admin/products/4d091b18afb3180f3d000111
Completed 302 Found in 49ms
It looks like the MONGODB command to update the font_ids is completely absent...
I'm partial to believing Mongoid Issue #357 is causing the problem. The logging above suggests that an update for the product's document_template.fonts (or font_ids) which seems to match the bug description.
(sidenote: I'm a bit confused where exactly the font_ids array comes from if not the :stored_as => :array. I'm not 100% certain which I should be modifying either but since font_ids is an Array and fonts is a Mongoid::Criteria, the path of least resistance is font_ids.)
From a data standpoint, :field and :embeds_* seem to be similar in that the information is embedded in the parent document.
Mongoid has a complicated back end. Therefore, the easiest way to diagnose this is to enable the driver's logging. Then we can look at the exact messages being sent to the database in both cases, and we're sure to get an answer.
Can you attach a logger when you connect to MongoDB and then post the relevant sections of log output?

Resources