Search::Elasticsearch Perl模块搜索特殊字符出现UTF-8错误如何解决
问题根因与解决方案
你遇到的报错和十六进制转义现象本质不是Search::Elasticsearch模块主动做了转换,而是你传入的查询内容编码不合法、且使用方式不符合模块的最佳实践,具体解决方法如下:
最优方案:直接传入Perl哈希结构作为查询体
Search::Elasticsearch原生支持直接传入Perl哈希格式的查询参数,模块会自动完成合法UTF-8格式的JSON序列化,完全避免编码问题,无需自己拼接JSON字符串,示例代码如下:
# 声明源码使用UTF-8编码,若代码中包含特殊字符字面量必须加这行 use utf8; use Search::Elasticsearch; # 构造查询哈希 my $query = { query => { bool => { must => [ { match => { "myattrs.comment" => { query => "hè testä", operator => "AND" } } }, { range => { "myattrs.creation_datetime" => { gte => "2020-01-01T00:00:00", lte => "2021-09-07T23:59:59" } } } ] } } }; # 直接传哈希给body参数 my $result = $e->search( index => $index_name, body => $query );
该方案生成的请求和你在Kibana控制台发送的请求完全一致,不会出现编码错误。
兼容方案:如果必须自行拼接JSON字符串
如果你的业务场景必须提前拼接好JSON字符串,需要主动确保字符串为合法UTF-8编码:
- 代码开头引入Encode模块处理编码
- 拼接后的JSON字符串手动转成UTF-8字节流再传入
示例代码如下:
use utf8; use Encode qw(encode_utf8); # 你的$params变量构造逻辑... my $json_body = encode_utf8("{ $params }"); my $result = $e->search( index => $index_name, body => $json_body );
额外说明
你看到的h\xe8 test\xe4这类十六进制格式,是JSON序列化工具遇到非UTF-8的Latin1单字节字符时的默认输出,0xe8是Latin1编码下è的字节值,并非模块主动做了转换,只要按上述方案保证输入内容为合法UTF-8编码,问题即可解决。
内容的提问来源于stack exchange,提问作者Manoj Agarwal
相关产品推荐
相关产品推荐

