最近在做商城项目使用ES8.13.0做商品复杂的检索功能时,遇到一个报错如下:
java
2024-07-05 10:47:53.994 ERROR 10708 --- [nio-7500-exec-1] com.tfq.exception.RRExceptionHandler : co.elastic.clients.transport.TransportException: node: http://127.0.0.1:9200/, status: 200, [es/search] Failed to decode response
java.lang.RuntimeException: co.elastic.clients.transport.TransportException: node: http://127.0.0.1:9200/, status: 200, [es/search] Failed to decode response
at com.tfq.service.impl.MallSearchServiceImpl.search(MallSearchServiceImpl.java:64) ~[classes/:na]
at com.tfq.app.SearchController.listPage(SearchController.java:23) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.23.jar:5.3.23]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) [spring-boot-actuator-2.6.13.jar:2.6.13]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.23.jar:5.3.23]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.23.jar:5.3.23]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.23.jar:5.3.23]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.68.jar:9.0.68]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.68.jar:9.0.68]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_221]
Caused by: co.elastic.clients.transport.TransportException: node: http://127.0.0.1:9200/, status: 200, [es/search] Failed to decode response
at co.elastic.clients.transport.ElasticsearchTransportBase.decodeTransportResponse(ElasticsearchTransportBase.java:404) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.transport.ElasticsearchTransportBase.getApiResponse(ElasticsearchTransportBase.java:363) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.transport.ElasticsearchTransportBase.performRequest(ElasticsearchTransportBase.java:147) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.elasticsearch.ElasticsearchClient.search(ElasticsearchClient.java:1923) ~[elasticsearch-java-8.13.0.jar:na]
at com.tfq.service.impl.MallSearchServiceImpl.search(MallSearchServiceImpl.java:59) ~[classes/:na]
... 55 common frames omitted
Caused by: co.elastic.clients.json.JsonpMappingException: Error deserializing co.elastic.clients.elasticsearch.core.search.Hit: jakarta.json.JsonException: Jackson exception (JSON path: hits.hits[0]._source) (line no=1, column no=244, offset=-1)
at co.elastic.clients.json.JsonpMappingException.from0(JsonpMappingException.java:134) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpMappingException.from(JsonpMappingException.java:121) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:218) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:148) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectBuilderDeserializer.deserialize(ObjectBuilderDeserializer.java:85) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpDeserializerBase$ArrayDeserializer.deserialize(JsonpDeserializerBase.java:318) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpDeserializerBase$ArrayDeserializer.deserialize(JsonpDeserializerBase.java:280) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:77) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer$FieldObjectDeserializer.deserialize(ObjectDeserializer.java:78) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:192) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:148) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:77) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectBuilderDeserializer.deserialize(ObjectBuilderDeserializer.java:79) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer$FieldObjectDeserializer.deserialize(ObjectDeserializer.java:78) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:192) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:148) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:77) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectBuilderDeserializer.deserialize(ObjectBuilderDeserializer.java:79) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.DelegatingDeserializer$SameType.deserialize(DelegatingDeserializer.java:43) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.DelegatingDeserializer$SameType.deserialize(DelegatingDeserializer.java:43) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.transport.endpoints.EndpointWithResponseMapperAttr$1.deserialize(EndpointWithResponseMapperAttr.java:56) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.transport.ElasticsearchTransportBase.decodeTransportResponse(ElasticsearchTransportBase.java:399) ~[elasticsearch-java-8.13.0.jar:na]
... 59 common frames omitted
Caused by: jakarta.json.JsonException: Jackson exception
at co.elastic.clients.json.jackson.JacksonUtils.convertException(JacksonUtils.java:39) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.jackson.JacksonJsonpMapper$JacksonValueParser.deserialize(JacksonJsonpMapper.java:142) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:77) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpMapperBase.deserialize(JsonpMapperBase.java:69) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.JsonpDeserializer$1.deserialize(JsonpDeserializer.java:108) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.NamedDeserializer.deserialize(NamedDeserializer.java:64) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer$FieldObjectDeserializer.deserialize(ObjectDeserializer.java:78) ~[elasticsearch-java-8.13.0.jar:na]
at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:192) ~[elasticsearch-java-8.13.0.jar:na]
... 78 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "skuId" (class com.tfq.vo.SearchResult), not marked as ignorable (7 known properties: "totalPages", "catalogVos", "brandVos", "products", "pageNum", "attrVos", "total"])
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 244] (through reference chain: com.tfq.vo.SearchResult["skuId"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1153) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:2241) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1793) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1771) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:316) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4881) ~[jackson-databind-2.17.0.jar:2.17.0]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3104) ~[jackson-databind-2.17.0.jar:2.17.0]
at co.elastic.clients.json.jackson.JacksonJsonpMapper$JacksonValueParser.deserialize(JacksonJsonpMapper.java:140) ~[elasticsearch-java-8.13.0.jar:na]
... 84 common frames omitted
2024-07-05 10:47:54.011 WARN 10708 --- [nio-7500-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [java.lang.RuntimeException: co.elastic.clients.transport.TransportException: node: http://127.0.0.1:9200/, status: 200, [es/search] Failed to decode response]
看第一个报错"status: 200, [es/search] Failed to decode response"在网上搜索是es请求设置Header有问题,搜了一圈发现设置了header并没有用。于是在仔细看第三个异常:
Error deserializing co.elastic.clients.elasticsearch.core.search.Hit: jakarta.json.JsonException: Jackson exception (JSON path: hits.hits[0]._source)
发现是请求es返回的结果类没有使用jackson的Json注释导致不能序列化转json。在对应的返回类上添加注释:
java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@Data
@JsonIgnoreProperties(ignoreUnknown=true)
public class SearchResult {
/**
* 查询的所有商品信息
*/
private List<SkuEsModel> products;
/**
* 当前页码
*/
private Integer pageNum;
/**
* 总记录数
*/
private Long total;
}
在service上发送请求即可获取对应es的索引product的查询数据。
java
public SearchResult search(SearchParam searchParam) {
SearchResult result = null;
ElasticsearchClient instance = elasticClient.getElasticsearchClient();
//1.动态构建出查询需要的DSL语句
//2.准备检索请求
SearchRequest searchRequest = buildSearchRequest(searchParam);
System.out.println("dsl:" + printDSL(searchRequest));
//3.执行检索请求
try {
SearchResponse<SearchResult> response = instance.search(searchRequest, SearchResult.class);
System.out.println("查询返回结果:"+response);
//result = buildSearchResult();
} catch(IOException e) {
throw new RuntimeException(e);
}
//4.分析响应数据封装成我们需要的格式
return result;
}
/**
* 准备检索请求
* 1.模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存),排序,分页,高亮,聚合分析
*
* @return 检索请求
*/
private SearchRequest buildSearchRequest(SearchParam searchParam) {
SearchRequest.Builder builder = new SearchRequest.Builder();
builder.index(EsConstant.PRODUCT_INDEX);
/**
* 模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存)
*/
//1.1.bool - must查询
BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
if(!StringUtils.isEmpty(searchParam.getKeyword())) {
boolQueryBuilder.must(
query -> query.match(
f -> f.field("skuTitle")
.query(searchParam.getKeyword())
)
);
}
//1.2.bool - filter - 按照三级分类id查询
if(searchParam.getCatelog3Id() != null) {
boolQueryBuilder.filter(
query -> query.term(
f -> f.field("catalogId")
.value(searchParam.getCatelog3Id()
.toString())
)
);
}
builder.query(b -> b.bool(boolQueryBuilder.build()));
//2.2.分页
builder.from(((searchParam.getPageNum() - 1) * EsConstant.PRODUCT_PAGE_NUM));
builder.size(EsConstant.PRODUCT_PAGE_NUM);
return builder.build();
}
结合以上代码整合到对应系统即可。