How highlight found word with Sunspot?

微笑、不失礼 提交于 2020-01-13 10:41:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!