当我早上醒来时,我在从Amazon Elasticsearch获取的搜索结果中遇到了Json解析错误的问题

前日还能正常使用Amazon Elasticsearch进行搜索,但早上突然不能用了。

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

由于出现了频繁的错误,这里是对应的解决办法共享。

环境 –

Note: The Chinese word “环境” literally means “environment” and can be used in various contexts such as natural environment, social environment, or even personal surroundings.

    • Amazon Elasticsearch

 

    • Elasticsearch(ver2系、5系)

 

    elasticsearch-rails-5.0.4

事件

解析Elasticsearch返回的JSON时出现错误。
出了什么问题?
以下是确认步骤的详细说明。

调查

    • エラー発生箇所に「binding.pry」を入れてそもそもどんなjsonデータをparseしようとしてエラーになっているのか調査

 

    bundle open elasticsearch-transportでエラーが起きていた箇所を確認。pryを使ってjsonの中身を確認
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中使用的faraday在Http通信中的默认设置是”Accept-Encoding: gzip”。

广告
将在 10 秒后关闭
bannerAds