2

I have a document model and I am using elastic search on it

My document model is as Follows

    require 'elasticsearch/model'

    class Document < ApplicationRecord
    include Elasticsearch::Model
    include Elasticsearch::Model::Callbacks
    belongs_to :user

    def self.search(query)
    __elasticsearch__.search(
    {
      query: {
      multi_match: {
      query: query,
      fields: ['name', 'service', 'description', 'tat', 'status']
    }
   },
   highlight: {
    pre_tags: ['<em>'],
    post_tags: ['</em>'],
    fields: {
      name: {},
      service: {},
      description: {},
      tat: {},
      status: {}
    }
   }
   }

  ) 
    end

  settings index: { number_of_shards: 1 } do
  mappings dynamic: 'false' do
  indexes :name, analyzer: 'english', index_options: 'offsets'
  indexes :service, analyzer: 'english'
  indexes :description, analyzer: 'english'
  indexes :tat, analyzer: 'english'
  indexes :status, analyzer: 'english'
  end
  end


 end

 Document.import force: true
 Document.__elasticsearch__.create_index! force: true 

My search Controller is as follows:

 def search
 if params[:q].nil?
  @documents = []
 else
  @documents = Document.search(params[:q])
 end
 end

My search view is as follows:

  <h1>Document Search</h1>

  <%= form_for search_path, method: :get do |f| %>
  <p>
  <%= f.label "Search for" %>
  <%= text_field_tag :q, params[:q] %>
  <%= submit_tag "Go", name: nil %>
  </p>
  <% end %>

  <ul>
  <% @documents.each do |document| %>
  <li>
  <h3>
    <%= link_to document.try(:highlight).try(:name) ? 
  document.highlight.name[0].html_safe : document.name,
    controller: "documents", action: "show", id: document._id %>
  </h3>
  <% if document.try(:highlight).try(:description) %>
    <% document.highlight.description.each do |snippet| %>
      <p><%= snippet.html_safe %>...</p>
    <% end %>
  <% end %>
  <% if document.try(:highlight).try(:service) %>
    <% document.highlight.service.each do |snippet| %>
      <p><%= snippet.html_safe %>...</p>
    <% end %>
  <% end %>
  <% if document.try(:highlight).try(:tat) %>
    <% document.highlight.tat.each do |snippet| %>
      <p><%= snippet.html_safe %>...</p>
    <% end %>
  <% end %>
  <% if document.try(:highlight).try(:status) %>
    <% document.highlight.status.each do |snippet| %>
      <p><%= snippet.html_safe %>...</p>
    <% end %>
  <% end %>


 </li>

  <% end %>
 </ul>

Now when I run a query with rental as the value in the query params name, it does not display the data on my search page even though the record with name book exists. On Running debugger for my search controller line

  @documents = Document.search(params[:q])

This is what I get

 <Elasticsearch::Model::Response::Response:0x007fcdde617430 @klass=[PROXY] 
 Document(id: integer, name: string, service: string, stamp_required: boolean, 
 default_price: string, tat: string, automated: boolean, template_url: string, 
 status: string, description: string, priorty: string, user_id: integer, 
 created_at: datetime, updated_at: datetime), @search=#

<Elasticsearch::Model::Searching::SearchRequest:0x007fcdde6175e8 @klass=
[PROXY] Document(id: integer, name: string, service: string, stamp_required:    
boolean, default_price: string, tat: string, automated: boolean, template_url: 
string, status: string, description: string, priorty: string, user_id: 
integer, created_at: datetime, updated_at: datetime), @options={}, 
@definition={:index=>"documents", :type=>"document", :body=>{:query=>
{:multi_match=>{:query=>"Rental Agreement", :fields=>["name", "service", 
"description", "tat", "status"]}}, :highlight=>{:pre_tags=>["<em>"], 
:post_tags=>["</em>"], :fields=>{:name=>{}, :service=>{}, :description=>{}, 
:tat=>{}, :status=>{}}}}}>>

I need to display the search result. What am I doing wrong?

Mahesh Mesta
  • 169
  • 7
  • what is the output of this: `@documents.results.to_a` ? – zauzaj Jul 24 '17 at 10:20
  • @zauzaj This is what I get for estamp as the query: [# _type="document" highlight=# – Mahesh Mesta Jul 24 '17 at 10:34
  • =#Estamp"] service=["Estamp"]>>>, # – Mahesh Mesta Jul 24 '17 at 10:36
  • _type="document" highlight=#Estamp"] service=["Estamp"]>>>] – Mahesh Mesta Jul 24 '17 at 10:36
  • sorry, can you update your question with those data to be more clear and structurized, as it's very hard to clarify how it looks on this way – zauzaj Jul 24 '17 at 12:10
  • @zauzaj Strangely testing with documents.results.to_a for a query search of data 'Rental Agreement' displays [ ].i.e empty array – Mahesh Mesta Jul 27 '17 at 05:58
  • that means that your search logic is not implemented properly. First thing I'd check is, do you have data on ES at all. `curl localhost:9200/_cat/indices?v`. If so, then try with some simpler query on only 1 field. That way you will find some solution to make it works and then continue improving. Try to play around with those things ;) – zauzaj Jul 27 '17 at 06:39
  • @zauzaj Yeah, finally I managed to resolve it. It had something to do with this line Document.__elasticsearch__.create_index! force: true. I commented it and started working. I do have another question though. Can you tell me how to implement "did you mean" feature with rails? The documentations that I've gone through are very confusing – Mahesh Mesta Jul 27 '17 at 09:30
  • I left answer, so you can accept it as good one, close this question, and open another one as that's totally diff topic you have. – zauzaj Jul 27 '17 at 10:47

1 Answers1

1

Document.__elasticsearch__.create_index! force: true actually forced to create index and clear all records there.

There are some other ways to create index like :

index_klass.__elasticsearch__.client.indices.create(index: 'index_name')

You can pass more options like mappings/settings but your data will be always persisted and not-touched !

Regards

zauzaj
  • 1,206
  • 12
  • 20