Вопрос

I have a problem with query with nested filter in it. Here is what I have:

  def search_with_filters(reservation_ids, query)
    search query: {
      filtered: {
        query: {
          query_string: {
            query: query
          }
        },
        filter: {
          nested: {
            path: 'reservation',
            query: {
              bool: {
                must: {
                  terms: {
                    'reservation.id' => reservation_ids
                  }
                }
              }
            }
          }
        }
      }
    }
  end

I have inspected elasticsearch documentation and as I understand it should work. Also I looked at Igor Motov's gist (elasticsearch contributor) where he explained the solution but it also did not work for me. Other articles were less informative thus I will not refer them here.

Here are the mapping of my model:

pry(main)> EmployeeReservation.mappings
=> #<Elasticsearch::Model::Indexing::Mappings:0x0000010fb120a0
 @mapping=
  {:user=>{:type=>"object", :properties=>{:name=>{:type=>"string"}}},
   :reservation=>
    {:nested=>true,
     :type=>"object",
     :properties=>
      {:time_start=>{:type=>"string"},
       :service_location_lane=>
        {:type=>"object", :properties=>{:name=>{:type=>"string"}}}}}},
 @options={},
 @type="employee_reservation">

Here is resulting query from the request:

pry(main)> EmployeeReservation.search_with_filters([1,2], '*Yury*').records
=> #<Elasticsearch::Model::Response::Records:0x00000103ba24b8
 @klass=
  [PROXY] EmployeeReservation(id: integer, reservation_id: integer, amount: decimal, created_at: datetime, updated_at: datetime, user_id: integer, rate: integer, duration: integer),
 @response=
  #<Elasticsearch::Model::Response::Response:0x00000103ba2508
   @klass=
    [PROXY] EmployeeReservation(id: integer, reservation_id: integer, amount: decimal, created_at: datetime, updated_at: datetime, user_id: integer, rate: integer, duration: integer),
   @records=#<Elasticsearch::Model::Response::Records:0x00000103ba24b8 ...>,
   @search=
    #<Elasticsearch::Model::Searching::SearchRequest:0x00000103ba27b0
     @definition=
      {:index=>"employee_reservations",
       :type=>"employee_reservation",
       :body=>
        {:query=>
          {:filtered=>
            {:query=>{:query_string=>{:query=>"*Yury*"}},
             :filter=>
              {:nested=>
                {:path=>"reservation",
                 :query=>
                  {:bool=>{:must=>{:terms=>{"reservation.id"=>[1, 2]}}}}}}}}}},
     @klass=
      [PROXY] EmployeeReservation(id: integer, reservation_id: integer, amount: decimal, created_at: datetime, updated_at: datetime, user_id: integer, rate: integer, duration: integer)>>>

And here is the error:

EmployeeReservation Search (6.1ms) {index: "employee_reservations", type: "employee_reservation", body: {query: {filtered: {query: {query_string: {query: "*Yury*"}}, filter: {nested: {path: "reservation", query: {bool: {must: {terms: {"reservation.id"=>[1, 2]}}}}}}}}}}
Elasticsearch::Transport::Transport::Errors::BadRequest: [400] {"error":"SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[km2oNhrpTc-oXLPo-x1B-g][employee_reservations][0]: SearchParseException[[employee_reservations][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\":{\"filtered\":{\"query\":{\"query_string\":{\"query\":\"*Yury*\"}},\"filter\":{\"nested\":{\"path\":\"reservation\",\"query\":{\"bool\":{\"must\":{\"terms\":{\"reservation.id\":[1,2]}}}}}}}}}]]]; nested: QueryParsingException[[employee_reservations] [nested] nested object under path [reservation] is not of nested type]; }]","status":400}
from /Users/FUT/.rvm/gems/ruby-2.0.0-p353@car_service/gems/elasticsearch-transport-1.0.1/lib/elasticsearch/transport/transport/base.rb:132:in `__raise_transport_error'

Could you please help?

EDIT 1:

I use elasticsearch version 1.1.0

Это было полезно?

Решение

By the looks of it, your mapping defines reservation as type object with nested set to true:

EmployeeReservation.mappings
   […]
   :reservation=>
    {:nested=>true,
     :type=>"object",
     […]

What you really need is to set type => "nested", as there is no nested property. Make sure to dump your index before setting the mapping and give it another try.

Please refer to the nested mapping docs for better information.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top