在elasticsearch中使用查询的嵌套过滤器

时间:2014-04-30 10:40:55

标签: ruby-on-rails ruby elasticsearch full-text-search

我的查询有嵌套过滤器问题。这就是我所拥有的:

  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

我已经检查了elasticsearch documentation,据我了解它应该有效。我还看了Igor Motov's gist(elasticsearch撰稿人),他在那里解释了解决方案,但它对我也没有用。其他文章信息量较少,因此我不会在这里提及。

以下是我的模型的映射:

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">

以下是来自请求的结果查询:

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)>>>

这是错误:

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'

你能帮忙吗?

编辑1:

我使用elasticsearch版本1.1.0

1 个答案:

答案 0 :(得分:1)

根据它的外观,您的映射将reservation定义为类型objectnested设置为true

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

您真正需要的是设置type => "nested",因为没有nested属性。 确保在设置映射之前转储索引并再试一次。

请参阅nested mapping docs以获取更多信息。