How to set infix & prefix indexing in sphinx search - ruby-on-rails-3

I want to have infix indexing for few fields and prefix indexing for some other fields in my table. Is there a way to do it in sphinx?
I'm looking for options infix_fields & prefix_fields in Sphinx with dict=keywords

To do this, you can set it per field in the index definition:
indexes name, :infixes => true
indexes location, :prefixes => true
The dict setting can only be set per-index, so if you want it for specific indices, add this to those index definitions:
set_property :dict => ‘keywords’
Or for all indices, add it to each environment in your config/thinking_sphinx.yml file:
development:
dict: keywords
test:
dict: keywords
production:
dict: keywords
Though at some point, I believe keywords will be (if it isn’t already) the default dict setting for Sphinx.

ThinkingSphinx::Index.define(:incident, DEFAULT_INDEX_OPTIONS.merge(name: "incident_#{i}"), &Searchable.beetilable_index('Incident', index_count: incident_index_count, index_id: i) {
indexes name
set_property :min_prefix_len => 3
})
#
# infix index (only for the title, symptom columns)
#
ThinkingSphinx::Index.define(:incident, DEFAULT_INDEX_OPTIONS.merge(name: "incident_#{i + incident_index_count + 1}"), &Searchable.beetilable_infix_index('Incident', index_count: incident_index_count, index_id: i) {
indexes location
set_property :min_infix_len => 3
})
end

Related

What is the difference between `[]=` and `add` for HTTP::Server::Response#headers?

I looked at the source code for both []= and .add when adding/manipulating headers. I'm still confused as to the reason why there are two ways to add/set headers. What are the differences between the two methods?
[]= replaces all header key content with a new array of value
puts response.headers["Accept-Language"] # => ["de"]
response.headers["Accept-Language"] = "de-CH" # or ["de-CH"]
puts response.headers["Accept-Language"] # => ["de-CH"]
.add checks if header key exist and append the value:
puts response.headers["Accept-Language"] # => ["de"]
response.headers.add "Accept-Language", "de-CH"
puts response.headers["Accept-Language"] # => ["de", "de-CH"]

How Can I extract the compete hash of parameters sent along with controler call in rails?

I can extract one by one like params[:id] but how to extract all of them like params[:all] or parameters['all'].
Parameters: {"id"=>"aom7v66e309yjkd2x0aq", "video_type"=>"trailer"}
Rails parameters are instances of HashWithIndifferentAccess, a subclass of Hash.
params.class
# => HashWithIndifferentAccess
params.is_a? Hash
# => true
You can get the entire Hash with params:
params
# => {"id"=>"aom7v66e309yjkd2x0aq", "video_type"=>"trailer"}
Or with #to_hash if you need a plain Hash:
params.to_hash
# => {"id"=>"aom7v66e309yjkd2x0aq", "video_type"=>"trailer"}
params.to_hash.class
# => Hash
The keys with #keys:
params.keys
# => ["id", "video_type"]
And the values with #values:
params.values
# => ["aom7v66e309yjkd2x0aq", "trailer"]
To extract specific keys, you can use #slice:
params = {"a"=>1, "b"=>2, "c"=>3}
params.slice("a", "c")
# => {"a"=>1, "c"=>3}
Or its counterpart #except:
params = {"a"=>1, "b"=>2, "c"=>3}
params.except("b")
# => {"a"=>1, "c"=>3}

Ruby on Rails - search in database based on a query

I have a simple form, where I set up a query that I want to browse, for example panasonic viera.
This is on how I search the term in database:
Product.where("name ilike ?", "%#{params[:q]}%").order('price')
The query looks like %panasonic viera%, but I would need to search the query this way: %panasonic%viera% - I need to find all products, where is in the title the word panasonic or viera... but how to make this query?
One solution would be to break up your query into individual terms and build a set of database queries connected by OR.
terms = params[:q].split
query = terms.map { |term| "name like '%#{term}%'" }.join(" OR ")
Product.where(query).order('price')
If you're using PostgreSQL, you can use pg_search gem. It's support full text search, with option any_word:
Setting this attribute to true will perform a search which will return all models containing any word in the search terms.
Example from pg_search:
class Number < ActiveRecord::Base
include PgSearch
pg_search_scope :search_any_word,
:against => :text,
:using => {
:tsearch => {:any_word => true}
}
pg_search_scope :search_all_words,
:against => :text
end
one = Number.create! :text => 'one'
two = Number.create! :text => 'two'
three = Number.create! :text => 'three'
Number.search_any_word('one two three') # => [one, two, three]
Number.search_all_words('one two three') # => []
How about via ARel
def self.search(query)
words = query.split(/\s+/)
table = self.arel_table
predicates = []
words.each do |word|
predicates << table[:name].matches("%#{word}%")
end
if predicates.size > 1
first = predicates.shift
conditions = Arel::Nodes::Grouping.new(predicates.inject(first) {|memo, expr| Arel::Nodes::Or.new(memo, expr)})
else
conditions = predicates.first
end
where(conditions).to_a
end
This isn't working?
WHERE name LIKE "panasonic" OR name LIKE "viera"

How can I get an ActiveRecord query to ignore nil conditions?

In order to avoid having to construct complicated dynamic SQL queries, I'd like to be able to just pass in nil values in my conditions, and have those ignored. Is that supported by ActiveRecord?
Here is an example.
event = Event.find(:all, :conditions => {
:title => params[:title],
:start_time => params[:start_time],
:end_time => params[:end_time]
}).first
In that particular case, if params[:start_time] is set to nil, ActiveRecord will search for those Events that have their start_time set to null. Instead, I'd like it to just ignore start_time. How do I do that?
You don't have to "create complicated dynamic SQL queries" to do what you need. Simply construct your conditions hash separately, and either exclude the null values at the time of creation or after you've created the hash.
conditions = {}
conditions[:title] = params[:title] unless params[:title].blank?
conditions[:start_time] = params[:start_time] unless params[:start_time].blank?
conditions[:end_time] = params[:end_time] unless params[:end_time].blank?
or
conditions = {:title => params[:title], :start_time => params[:start_time], :end_time => params[:end_time]}
conditions.delete_if {|k,v| v.blank? }
or
conditions = params.reject {|k,v| !([:title, :start_time, :end_time]).include?(k) }
but that last form will only work if the keys are actually symbols. In Rails the params hash is a HashWithIndifferentAccess which allows you to access the text keys as symbols. Of course you could just use the text values in your array of keys to include if necessary.
and then query with your pre-built conditions hash:
event = Event.find(:all, :conditions => conditions).first

Sphinx Scope Returning Nothing

I'm trying to create a simple scope that sphinx will index (Ruby on Rails). The normal scope returns what it should, the sphinx scope returns no results.
define_index do
# fields
indexes :name
indexes author
indexes description
indexes list_of_tags
indexes approved
# attributes
has created_at, updated_at, downloads
# delta indexing
set_property :delta => true
# weighting fields
set_property :field_weights => {
:name => 10,
list_of_tags => 6,
author => 5,
description => 4,
}
end
normal scope:
scope :approved, where(:approved => true)
sphinx scope:
sphinx_scope(:approval_scope) {
{:conditions => {:approved => "true"}}
}
Approved is a boolean field, however, since I'm indexing it as a field, I believe its value is treated as a String. Regardless, letting the value of the sphinx scope be "true" or true makes no difference - Theme.approval_score still returns 0 results unlike Theme.approval. I hope I'm missing something simple..
make the approved with has
define_index do
# fields
...
has approved
...
end
then
sphinx_scope(:approval_scope) {
{:with => {:approved => true}}
}