问题
I want to highlight found words in text, for example, as shown here.
As far as I know I must follow these steps:
1) In my model, I must add :stored => true
option to the field which I want to highlight:
searchable do
text :title, :stored => true
text :description
end
2) In my controller, I have to declare which field I want highlighted:
def search
@search = Article.search do
keywords params[:search] do
highlight :title
end
end
end
3) In the view I'm not sure what to do, I tried this:
- @search.each_hit_with_result do |hit, result|
%p= link_to raw(hit_title(hit)), article_path(result)
It is what doing method hit_title
:
def hit_title(hit)
if highlight = hit.highlight(:title)
highlight.format { |word| "<font color='green'>#{word}</font>" }
else
h(hit.result.title)
end
end
But it doesn't work as expected, it always highlights the first word of the title, even if the searched word is at the end of it.
Is there an easier way to do this?
回答1:
I bumped into this looking for a solution to render highlights from sunspot search on rails view.
I didn't find much of a ready solution anywhere, so I used part of this post to make one of my one. I am quite new to rails so this might not be fully the RoR way.
In my case, I did a full text search on two fields, call them notes
and description
.
In order to be able to render to html the highlights, I introduced a hash of values containing the id of the record, the name of the column and its highlighted value, adequately formatted. This allows me to highlight the search results on different fields.
entry.rb:
searchable do
text :description, :stored => true
text :notes, :stored => true
end
entries_controller.rb:
@search = Entry.search
if params[:search].nil? || params[:search].empty?
stext=''
else
stext=params[:search]
end
fulltext stext, :highlight => true
paginate(page: params[:page], :per_page => 10)
end
@entries=@search.results
@results=Hash.new
@search.hits.each do |hit|
hit.highlights(:description).each do |highlight|
id=hit.primary_key.to_s.to_sym
fr=highlight.format { |word| "<result>#{word}</result>" }
@results.merge!(id => ["description",fr])
end
hit.highlights(:notes).each do |highlight|
id=hit.primary_key.to_s.to_sym
fr=highlight.format { |word| "<result>#{word}</result>" }
@results.merge!(id => ["notes",fr])
end
end
and on the view, wherever I want to render any value of those, I do the following:
<% @entries.each do |f| %>
<% j=f[:id].to_s.to_sym %>
<% if !@results[j].nil? && @results[j][0]=="description" %>
<%= @results[j][1].html_safe %>
<% else %>
<%= f[:description] %>
<% end %>
[...] (likewise for notes)
<% end %>
Please, note I created a css definition for <result>
markup to make the text notable.
回答2:
Code looks good to me for highlighting the first matching word in the title, since I have similar code. Have you tried rebuilding your solr index and restarting the servers?
Also, can you try reverting your solrconfig.xml to its default values? Someone had a similar problem after modifying solrconfig.xml, Ref https://groups.google.com/forum/#!searchin/ruby-sunspot/highlight/ruby-sunspot/kHq0Dw35UWs/ANIUwERArTQJ
If you want to override the highlighting option in solrconfig.xml, search for max_snippets on this site http://outoftime.github.io/ . You may want to try options like
highlight :title, :max_snippets => 3, :fragment_size => 0 # 0 is infinite
回答3:
Are you using substring search? I've got the same problem here and realized that enabling substring match by following sunspot wiki tutorial led to the problem.
来源:https://stackoverflow.com/questions/7161499/how-highlight-found-word-with-sunspot