ES的java客户端中SearchRequest和SearchResponse的序列化和反序列化

Elastcsearch官方提供了一个elasticsearch-rest-high-level-client,作者在写bug的时候需要将其中的ActionRequest(子类包括SearchRequest、IndexRequest、UpdateRequest等)和SearchResponse类分别做序列化和反序列化。

首先,这两个类都没有实现Serializable接口也无法直接用Json工具序列化为Json字符串。但是官方给我们提供了其它方法,亲测有效,以下作为记录:

ActionRequest(使用SearchRequest作例子):

官方提供了readFrom(StreamInput in)和writeTo(StreamOutput out)方法供使用

public abstract class ActionRequest extends TransportRequest {

  ...

    @Override
    public void readFrom(StreamInput in) throws IOException {
        super.readFrom(in);
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        super.writeTo(out);
    }
...
}

所以,我们实现序列化的核心代码如下:


        BytesStreamOutput output = new BytesStreamOutput();
        actionRequest.writeTo(output);
        //用base64进行编码(如果没有这步,反序列化时会失败)
        String s = BaseCoder.encryptBASE64(output.bytes().toBytesRef().bytes);

反序列化:

         //base64解码
        byte[] s1 = BaseCoder.decryptBASE64(s);
        BytesStreamOutput bytesStreamOutput = new BytesStreamOutput();
        bytesStreamOutput.write(s1);

        //设置解析器
        IndicesModule indicesModule = new IndicesModule(Collections.emptyList());
        SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
        List<NamedWriteableRegistry.Entry> entries = new ArrayList<>();
        entries.addAll(indicesModule.getNamedWriteables());
        entries.addAll(searchModule.getNamedWriteables());
        NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry(entries);
        //转换成输入流
        StreamInput in= new
NamedWriteableAwareStreamInput(bytesStreamOutput.bytes().streamInput(), namedWriteableRegistry);
        
        //还原
        SearchRequest request = new SearchRequest();
        actionRequest.readFrom(in);
       

SearchResponse:

作者在对SearchResponse进行序列化处理时发现上面的办法行不通,于是换了一个办法。es给我们提供了json的解决方式(XContent)。

序列化:

 XContentBuilder builder = XContentFactory.jsonBuilder();
        XContentBuilder xContent = searchResponse.toXContent(builder, ToXContent.EMPTY_PARAMS);
        String jsonResponse = xContent.string();

反序列化:

 NamedXContentRegistry namedXContentRegistry = new NamedXContentRegistry(getDefaultNamedXContents());
        XContentParser parser = JsonXContent.jsonXContent.createParser(namedXContentRegistry, jsonResponse);

 SearchResponse response= SearchResponse.fromXContent(parser);
private static List<NamedXContentRegistry.Entry> getDefaultNamedXContents() {
        Map<String, ContextParser<Object, ? extends Aggregation>> map = new HashMap<>();
        //这里设置统计字段(Aggregation)
        map.put(TopHitsAggregationBuilder.NAME, (p, c) -> ParsedTopHits.fromXContent(p, (String) c));
        map.put(DateRangeAggregationBuilder.NAME, (p, c) -> ParsedDateRange.fromXContent(p, (String) c));
        map.put(FilterAggregationBuilder.NAME, (p, c) -> ParsedFilter.fromXContent(p, (String) c));
        map.put(StringTerms.NAME, (p, c) -> ParsedStringTerms.fromXContent(p, (String) c));
        map.put(LongTerms.NAME, (p, c) -> ParsedLongTerms.fromXContent(p, (String) c));
        map.put(DoubleTerms.NAME, (p, c) -> ParsedDoubleTerms.fromXContent(p, (String) c));
        List<NamedXContentRegistry.Entry> entries = map.entrySet().stream()
                .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue()))
                .collect(Collectors.toList());
        SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.EMPTY_LIST);
        //普通字段
        entries.addAll(searchModule.getNamedXContents());
        return entries;
    }

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
Java,可以使用Jackson或Gson等库来序列化反序列化ESSearchRequest。以下是使用Jackson库实现序列化反序列化的示例代码: ```java import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import java.io.IOException; public class SearchRequestSerialization { public static void main(String[] args) throws IOException { // 创建一个SearchRequest对象 SearchRequest searchRequest = new SearchRequest("my_index"); // 创建一个SearchSourceBuilder对象,并设置查询条件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchQuery("my_field", "my_query")); // 将SearchSourceBuilder对象设置为SearchRequest的主体 searchRequest.source(searchSourceBuilder); // 使用Jackson库序列化SearchRequest对象 ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(searchRequest); System.out.println("Serialized SearchRequest: " + json); // 使用Jackson库反序列化SearchRequest对象 SearchRequest deserializedSearchRequest = mapper.readValue(json, SearchRequest.class); System.out.println("Deserialized SearchRequest: " + deserializedSearchRequest); // 使用XContentBuilder序列化SearchRequest对象 XContentBuilder builder = XContentFactory.jsonBuilder().value(searchRequest); String json2 = builder.string(); System.out.println("Serialized SearchRequest using XContentBuilder: " + json2); } } ``` 这里同时演示了如何使用XContentBuilder类序列化SearchRequest对象。注意,在使用XContentBuilder序列化时,需要将SearchRequest对象作为value传入builder

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值