LoginSignup
2
1

More than 5 years have passed since last update.

朝起きたらAmazon Elasticsearchから取得した検索結果でJson Parse Errorが起きた件

Last updated at Posted at 2017-10-04

前日まで普通にAmazonElasticsearchの検索が使えたのに、朝急に

MultiJson::ParseError: 822: unexpected token at '�'

というエラーが頻発したので、その対処方法の共有です。

環境

  • Amazon Elasticsearch
  • Elasticsearch(ver2系、5系)
  • elasticsearch-rails-5.0.4

事象

Elasticsearchから返ってきたjsonをparseしてエラー。
何が起きたのか?
以下確認手順を記載。

調査

  • エラー発生箇所に「binding.pry」を入れてそもそもどんなjsonデータをparseしようとしてエラーになっているのか調査 bundle open elasticsearch-transportでエラーが起きていた箇所を確認。pryを使ってjsonの中身を確認
elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/serializer/multi_json.rb
module Elasticsearch
  module Transport
    module Transport
      module Serializer

        # An abstract class for implementing serializer implementations
        #
        module Base
          # @param transport [Object] The instance of transport which uses this serializer
          #
          def initialize(transport=nil)
            @transport = transport
          end
        end

        # A default JSON serializer (using [MultiJSON](http://rubygems.org/gems/multi_json))
        #
        class MultiJson
          include Base

          # De-serialize a Hash from JSON string
          #
          def load(string, options={}) 
            ::MultiJson.load(string, options) <<<<< ここのstringの中身を確認
          end

          # Serialize a Hash to JSON string
          #
          def dump(object, options={})
            ::MultiJson.dump(object, options)
          end
        end
      end
    end
  end
end

  • 中身をみるとjsonデータでなく、何かエンコーディングされたような形式ものになっていた
  • なぜそうなったのか・・・。AmazonElasticsearchの仕様変更でgzip形式返すようになった。

対応

Elasticsearchの接続を行っていた箇所に以下のような修正を追加

      Elasticsearch::Client.new(
        hosts: hosts,
        randomize_hosts: true,
        request_timeout: 10,
        reload_connections: false,
        sniffer_timeout: 3,
        reload_on_failure: false,
        transport_options: { headers: { 
                                                             content_type: 'application/json',
                                                           "Accept-Encoding": "" <<<<< ここを追加
                                                          }
                                                     }, 
        log: true
      ) do |f|
        f.request :aws_signers_v4,
                   credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']),
                   service_name: 'es',
                   region: 'ap-northeast-1'
        f.adapter Faraday.default_adapter
      end

こちらを参考にしました。

<追記> 自分が忘れないようにするためのメモ: elasticsearch-railsの方でHttp通信で使っているfaradayは「Accept-Encoding: gzip」 がデフォルトの設定らしい。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1