首页 > 解决方案 > 如何在 Spring Project 中使用 ElasticSearch 的 NativeSearchQueryBuilder 返回单个对象?

问题描述

我正在使用 NativeSearchQueryBuilder 来形成查询,如下所示:

 String[] includeFields = new String[]{"idDl", "clientName"};
 String[] excludeFields = new String[]{"Address"};
 Query searchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchQuery("idDl", idDl))
                .withSourceFilter(new FetchSourceFilter(includeFields, excludeFields))
                 .build();
return elasticsearchRestTemplate.queryForObject((StringQuery) searchQuery, User.class);

我想返回没有特定字段的单个对象,这是异常的堆栈跟踪:

java.lang.ClassCastException: org.springframework.data.elasticsearch.core.query.NativeSearchQuery cannot be cast to org.springframework.data.elasticsearch.core.query.StringQuery
at com.user.services.UserQueryServiceImpl.getUserById(UserQueryServiceImpl.java:37) ~[classes/:na]
at com.User.controllers.UserController.getFilteredUserById(UserController.java:100) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_231]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_231]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_231]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_231]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.33.jar:9.0.33]

标签: spring-bootspring-mvcelasticsearchspring-dataspring-data-elasticsearch

解决方案


首先queryForObject已弃用,您应该使用searchOne(). 至于你的错误:

您创建一个,将其分配给类型NativeSearchQuery为 的变量;没关系。但是,您为什么要尝试将其转换为 a ?searchQueryQueryStringQuery

NativeSearchQuery并且StringQuery都实现了Query,所以只需传递您的查询实例:

return elasticsearchRestTemplate.queryForObject(searchQuery, User.class)

编辑 Spring Data Elasticsearch 3.2.x:

你应该使用

<T> List<T> queryForList(SearchQuery query, Class<T> clazz);

在那个版本中,仍然有实现的SearchQuery接口NativeSearchQuery。从返回的列表中,检查它是否包含任何元素,然后使用第一个。


推荐阅读