Sunspot and Solr: Google-like "site:" in search - ruby-on-rails

I'm fairly new to Sunspot and Solr.
I'd like to implement something similar to the Google site: phrase in searches, so that when I search for
something
I get all records related to "something". However, if they search
something site:example.com
It only displays results where the site attribute is example.com.
At the moment I've got:
searchable do
text :full_text
text :title, :boost => 5
text :excerpt
end
Do I need to index the site attribute? How would I implement the above idea?

No. Just make sure you gsub your params[:query] in your controller. Extract the value next to site: and add a where close to match the site. You'll be left with something.

Related

How can I match a partial string to a database's object's attribute? Regexp?

I have a database containing a list of movies. A typical entry look like this:
id: 1,
title: "Manhatten and the Murderer",
year: 1928,
synopsis: 'some text...'
rating: 67,
genre_id, etc. etc.
Now I'm trying to make a series of search tests pass and so far I have made a single test case pass where if you type the title "Manhatten and the Murderer" in a text field it will find the movie that you want. The problem is with partial matching.
Now I'd like a way to search "Manhat" and match the record "Manhatten and the Murderer". I also want it to match with any movie that has "Manhat" in it. For example, it would return maybe 2 or 3 others like title: "My life in Manhattan", title: "The Big Apple in Manhattan" etc. etc.
Below is the code that I have so far in my Movie model:
def self.search(query)
# Replace this with the appropriate ActiveRecord calls...
if query =~ where(title:)
#where(title: query)
binding.pry
end
end
My question is, how can I set this up? My problem is the "where(title:) line. One thought was to use Regexp to match the title attribute. Any help would be appreciated! Thanks.
Use a query that searches a substring in between:
name = "Manhattan"
Movie.where("title like ?", "%#{name}%")
For example:
%Manhattan will get you: Love in Manhattan
Manhattan% will get: Manhattan and Company
%Manhattan% will get you both: [Love in Manhattan, Manhattan and Company]
But, if you're searching through movies synopsis, you should use Thinking Sphinx or Elastic Search
For example, with Elastic Search, you could set the synopsis like this:
Add app/indices/movie_index.rb:
ThinkingSphinx::Index.define :movie, :with => :active_record do
# fields
indexes title, :sortable => true
indexes synopsis
end
Index your data with rake ts:index
And then run Sphynx with: rake ts:start
You can search just like this:
Movie.search :conditions => {:synopsis => "Manhattan"}
Elastic Search is a great alternative to ThinkingSphinx, there's even a RailsCast about it, so you should definitely take a look to see what really suites you best... Hope this helps!
You do not need regex to find movies that have the search string. You can use SQL query like this:
Movie.where('title LIKE ?','Batman%')
That would return all movies start with "Batman"
Movie.where('title LIKE ?','%Batman%')
That would return all movies that have Batman anywhere in it's title.
I think you figured out the '%' is a joker character in the query.
One option is to run a search server alongside your Rails application. It is certainly my go to solution. This route offers a ton of features not found within Rails itself and might be overkill, but worth consideration.
I use Sphinx and implement it using the thinking-sphinx gem.
Resources:
http://pat.github.io/thinking-sphinx/
http://sphinxsearch.com/

Sunspot Solr search parameter "with" not working with strings

I'm developing a Ruby on Rails application using Sunspot Solr as an indexer.
The thing is i try to use the parameter of the search with :, using strings and it doesn't seem to work. If i pass an int it works fine. Anyone knows how to do it with strings (if it's possible)?
An example of the search i want to do is:
#search = Sunspot.search(Record) do
fulltext params[:query]
with :checked, "Checked"
end
:checked is an attribute of the table Record and it validates if a record is checked so it can't be edited.
PD: I'm doing it this way because MySQL doesn't accept booleans.
Figured it out!
It turns out strings are a little more delicate, so you have to use:
with(:checked).equal_to("any_value")
For more information see:
https://github.com/sunspot/sunspot/wiki/Scoping-by-attribute-fields

How to build sort urls on Rails?

I am working on the index page of a listing controller, which needs several sort options. Query string is needed to determine the sort option that is active for the current page. I have used a workaround for this problem by hardcoding the query string into the sort links:
=link_to "Lowest Price","/listings?sort_by=price&order=asc", :class=>"#{'active' if request.query_string =~ /sort_by=price&order=asc/ }"
But there are two problems with this. First, this is too fragile. Second, it doesn't support a search query nor any other parameters -- otherwise it breaks.
What I need is a way to change the sort options without assuming that the query string will stay intact...
Not sure if there is a best practice for doing this. I'm taking the long road and just adding helpers to parse url to hash, hash to url, and I still don't know what to do about the active link problem. It could be a while to do all that.
Any suggestions would be appreciated.
You can do this by providing key/value pairs to any URL helper. For example:
listings_url(:sort_by => "asc", :order => "asc")

Sunspot indexing and searching tags returns everything

I am using act_as_taggable_on for tagging in our projects, along with sunspot/solr for searching.
We get a strange unexpected result. First our setup (short version):
Model:
Class Person
has_many :projects
searchable do
string :project_tags, :multiple => true do
projects.map { |p| p.tag_list}.flatten
end
end
Taglist is a method from act_as_taggable_on which returns an array of tags for each projects (f.e. ["foo", "bar"]). We index the project tags for the project members.
When, in our controller, we do:
Person.search() do
with(:project_tags).any_of(params[:tags])
end
This returns the right people. So far so good.
The Problem
We want to be able to search for multiple tags. So, per sunspot instructions, we pass along an array. The code looks roughly like this:
#tags_array= params[:tags].split(/ /)
Person.search() do
with(:project_tags).any_of(#tags_array)
end
Now Sunspot gives us every person as a result, no matter what tags we use! We have been testing this in the console like crazy, but can't understand where we are going wrong.
Any help would be appreciated!
Erwin
Ok we "solved" this ourselves and i'll report it back here in case anyone comes looking with the same question.
Somehow Sunspot doesn't like #tags_array in our search declaration, after some testing any #variable will not work. As soon as we changed it to:
tags_array= params[:tags].split(/ /)
Person.search() do
with(:project_tags).any_of(tags_array)
end
it worked.
Cheers,
Erwin

How do i go about searching in Ruby on Rails?

I would like to implement a simple search. Let's say the user enters 'york', then I would like to find all records that has a matching substring like 'new york' or 'yorkshire'.
So far I have figured out I will have to use the find method, but I can't figure out how to match for substrings.
city = params[:q]
User.find(:all, :conditions=>["city like :text", {:text=>"%#{city}%"} ] )
You might want to take a look at the Thinking Sphinx plugin for doing such full text search . Solr is also another option .

Resources