当我早上醒来时,我在从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”。