動かざることバグの如し

近づきたいよ 君の理想に

Elasticsearchの検索でqueryとrangeを同時に付けるとUnknown key for a START_OBJECT

rubyからElasticsearch使おうとしたらエラーになったのでメモ

環境

  • Ubuntu 16.04
  • Elasticsearch 5
  • elasticsearch-ruby 5.0.4

失敗したコード

require 'elasticsearch'

client = Elasticsearch::Client.new({
  log: false,
  hosts: {
    host: 'localhost',
    port: 9200
  }
})

q = {
  query: {
    query_string: {
      default_field: 'subject',
      default_operator: 'AND',
      query: "ruby",
    },
  },
  filter: {
    range: {
      created_date: {
        gte: "2017-12-01",
        lte: "2017-12-25"
      }
    }
  }
}

data = client.search(index: 'myindex', type: 'movies', body: q)
puts data.to_json

一見イケそうだがエラーになる。てかElasticsearchバージョン2系はこれでいけた

/Users/hoge/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/base.rb:202:in `__raise_transport_error': [400] {"error":{"root_cause":[{"type":"parsing_exception","reason":"Unknown key for a START_OBJECT in [filter].","line":1,"col":104}],"type":"parsing_exception","reason":"Unknown key for a START_OBJECT in [filter].","line":1,"col":104},"status":400} (Elasticsearch::Transport::Transport::Errors::BadRequest)
from /Users/hoge/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/base.rb:319:in `perform_request'
from /Users/hoge/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/http/faraday.rb:20:in `perform_request'
from /Users/hoge/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/client.rb:131:in `perform_request'
from /Users/hoge/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/elasticsearch-api-5.0.4/lib/elasticsearch/api/actions/search.rb:183:in `search'
from sugukesu.rb:29:in `<main>'

Unknown key for a START_OBJECT in [filter]ってなんだよとか思って色々調べていたら、queryとrangeを併用できないらしい

正しいのは以下

q = {
  query: {
    bool: {
      must: [
        {
          query_string: {
            default_field: 'subject',
            default_operator: 'AND',
            query: "ruby",
          },
        },
        {
          range: {
            created_date: {
              gte: "2017-12-01",
              lte: "2017-12-25"
            }
          }
        }
      ]
    } 
  }
}