Elasticsearch-rails Multi Match Query Not Working

1.1k Views Asked by At

I'm about sick of ES. Nothing ever works. With that said here is my next issue with ES.

I'm using the elasticsearch-rails gem.

When I run a curl command I can query with a multi_match and get the expected results like this:

curl -XGET 'localhost:9200/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "multi_match" : {
      "query":    "NY", 
      "fields": [ "street", "state" ] 
    }
  }
}
'
{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.47000363,
    "hits" : [
      {
        "_index" : "addresses",
        "_type" : "address",
        "_id" : "1",
        "_score" : 0.47000363,
        "_source" : {
          "street" : "Somewhere Else Rd",
          "city" : "Somewhere",
           "state" : "NY",
          "zip" : "88329"
        }
      },
      {
        "_index" : "addresses",
        "_type" : "address",
        "_id" : "2",
        "_score" : 0.47000363,
        "_source" : {
          "street" : "Somewhere Drive",
          "city" : "Somewhere",
          "state" : "NY",
          "zip" : "42293"
        }
      }
    ]
  }
} 

With the ruby code that does the same thing, I get 0 results. I don't get it.

Address Model:

settings index: { number_of_shards: 1 } do
  mappings dynamic: 'false' do
    indexes :street, analyzer: 'keyword'
    indexes :city, analyzer: 'keyword'
    indexes :state, analyzer: 'keyword' 
    indexes :zip, analyzer: 'keyword'
  end
end

def as_indexed_json(options={})
    as_json(
        only: [:street, :city, :state, :zip]
    )
 end

Controller Action:

 def search
    Address.all.import force: true
    @addresses = Address.all
    puts @addresses.size

     @addresses = Address.search(
           query: { 
             multi_match: {
                 query: "NY",
                 fields: ['street', 'state']
             }
          }
          )
          puts @addresses.size
end

The only reason I am reindexing every time I call the search function is for debug purposes only. Here is the console output.

Started GET "/addresses/search?q=1" for 75.65.92.24 at 2017-12-20 04:35:02 +0000
Cannot render console from 75.65.92.24! Allowed networks: 127.0.0.1, ::1, 
127.0.0.0/127.255.255.255
Processing by AddressesController#search as */*
  Parameters: {"q"=>"1"}
  Address Load (0.2ms)  SELECT  "addresses".* FROM "addresses" ORDER BY 
"addresses"."id" ASC LIMIT ?  [["LIMIT", 1000]]
  CACHE Address Load (0.0ms)  SELECT  "addresses".* FROM "addresses" ORDER 
BY "addresses"."id" ASC LIMIT ?  [["LIMIT", 1000]]
   (0.2ms)  SELECT COUNT(*) FROM "addresses"
3
0
  Rendering addresses/search.js.erb
  Rendered collection of addresses/_address.html.erb [0 times] (0.0ms)
  Rendered addresses/search.js.erb (4.0ms)
Completed 200 OK in 334ms (Views: 8.8ms | ActiveRecord: 1.4ms)
1

There are 1 best solutions below

3
On

This happened to me once and it had to do with the fact I was trying to declare the index with the wrong data type (keyword in this case). I think you don't need to declare your index like that, since what you need seems pretty standard.

Try removing the entire settings block, then delete your index

Model.__elasticsearch__.delete_index!

recreate your index

Model.__elasticsearch__.create_index!

index your elements

instance.__elasticsearch__.index_document

and search

Here is a sample multisearch that worked for me:

  def as_indexed_json(options={})
    h = {
      "id" => id,
      "author_name" => author_name,
      "author_email" => author_email,
      "content_title" => content_title,
      "content" => content,
      "circle_name" => circle_name.downcase,
      "updated_at" => updated_at.to_i
    }
  end

then search:

  search_params = {
    query: {
      multi_match: {
        query: query.downcase,
        fields: ["author_name", "author_email", "content_title", "content", "circle_name"]
      }
    },
    sort: [
      { updated_at: {order: "desc"}},
      "_score"
    ],
  }

  Post.__elasticsearch__.search(search_params).results

Maybe it will help