【问题标题】:Get all documents from an index using spring-data-elasticsearch使用 spring-data-elasticsearch 从索引中获取所有文档
【发布时间】:2017-09-11 07:25:01
【问题描述】:

我正在尝试使用 Spring Boot 连接到我的外部 ElasticSearch 服务器。

如果我从命令行执行 curl,我会得到预期的结果。

curl "http://ipAddr:9200/indexName/TYPE/_search?pretty=true"

但是当我尝试通过 Spring Boot 访问它时出现此错误。

<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Mon Sep 11 12:39:15 IST 2017</div><div>There was an unexpected error (type=Internal Server Error, status=500).</div><div>Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0]-&gt;org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl[&quot;facets&quot;])</div></body></html>

不知道为什么是NullPointerException,什么是aggregartion.impl

这是我的 Spring 应用程序:

控制器:

@RestController
public class PojoController {

    @Autowired
    PojoService pojoService;

    @RequestMapping(value = "/", method=RequestMethod.GET)
    public @ResponseBody String index() {
        return new String("Welcome:)");
    }

    @RequestMapping(value = "/all", method = RequestMethod.GET,
            produces = { MediaType.APPLICATION_JSON_VALUE })
    @ResponseBody List<POJO> findAll() {
        try {
            List<POJO> pojoObj = pojoService.findAll();
            return pojoObj;
        } catch (Exception exp) {
            exp.printStackTrace();
            return null;
        }
    }
}

存储库:

@Repository
public interface PojoRepository extends ElasticsearchRepository<POJO, Integer> {

    List<POJO> findAll();

}

服务:

@Service
public class POJOServiceImpl implements POJOService{

    private POJORepository pojoRepository;

    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    public void setPojoRepository(PojoRepository pojoRepository) {
        this.pojoRepository = pojoRepository;
    }

    public POJO findOne(String id) {
        return pojoRepository.findOne(id);
    }

    public List<POJO> findAll() {
        return (List<POJO>) pojoRepository.findAll();
    }

}

POJO 类:

@Document(indexName = "INDEX", type = "TYPE")
public class POJO {

     @Id
     private Integer id;
     private String name;

     public POJO(){
         // empty
     }



    public POJO(Integerid, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    // getters and setters
}

我应该能够查询索引中的所有文档。稍后,我将尝试使用过滤器等。

感谢任何帮助。谢谢:)

【问题讨论】:

    标签: spring elasticsearch spring-data-elasticsearch


    【解决方案1】:

    看起来 Jackson 在处理您的 POJO 时遇到了问题(可能与此问题有关:DATAES-274) - 有问题的部分是在存储库中从 Iterable 集合转换为 List

    更新

    对于存储库,spring-data-elasticsearch 的行为与您的预期有些不同。以你为例:

    @Repository
    public interface PojoRepository extends ElasticsearchRepository<POJO, Integer> {
        List<POJO> findAll();
    }
    

    在调用你的休息控制器之后:

    List<POJO> pojoObj = pojoService.findAll();
    

    在调试器中你会看到这样的:

    您会认为pojoObj 列表包含 POJO 类的对象。 惊喜出现了 - pojoObj ArrayList 包含一个 AggregatedPageImpl 类型的对象,其 content 字段是包含您的 POJO 对象的正确列表。 这就是你得到的原因:

    Could not write JSON: ... java.util.ArrayList[0]->org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl[\"facets\"])
    

    正如我之前写的,Jackson 在序列化 POJO 对象时无法处理这个问题。

    解决方案 1

    让存储库返回Iterable 集合(默认)。

    @Repository
    public interface PojoRepository extends ElasticsearchRepository<POJO, Integer> {
    
    }
    

    将转换部分移至服务,但使用一些实用方法(此处使用 Guava)以使其如下所示:

    import com.google.common.collect.Lists;
    
    public List<POJO> findAll() {
        return Lists.newArrayList(pojoRepository.findAll());
    }
    

    解决方案 2

    在存储库中使用Page(此处为不带参数的简化版本):

    @Repository
    public interface PojoRepository extends ElasticsearchRepository<POJO, Integer> {
        Page<TestDto> findAll();
    }
    

    如果您仍想对列表进行操作 - 从服务页面获取内容:

    public List<POJO> findAll() {
        return testDtoRepository.findAll().getContent();
    }
    

    【讨论】:

    • 我从 List 更改为 Iterable,但仍然出现相同的错误。
    • 您是否也将POJOServiceImpl 中的findAll() 方法更改为Lists.newArrayList(pojoRepository.findAll())(而不是转换为List)?
    • 没有。即使在那里,我也没有获得列表,而是返回 Iterable,
    • 感谢您指出Iterable 是从findAll() 返回的,我尝试使用Page&lt;POJO&gt; 进行分页,令人惊讶的是我不再收到该错误。
    • 太棒了!由于我正在调试代码以查找错误的确切原因 - 我更新了我的答案,以防其他人遇到同样的问题。
    猜你喜欢
    • 2021-12-24
    • 2019-06-02
    • 2021-07-02
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多