首页 文章

如何将Elasticsarch的结果连接到Spring的REST API响应中

提问于
浏览
0

我已经使用Spring开发了一个REST API条目,它在Elasticsearch中进行搜索,现在我想返回ES找到的任何结果作为响应 . 我不关心搜索结果,我不知道其中的JSON结构 . 我只是想把它还给客户 .

我希望这样的东西能起作用:

@RequestMapping(value = "/search/{index:.*}", method = RequestMethod.GET)
public void search(@PathVariable String index, @RequestParam Map allRequestParams, HttpServletResponse response)
    throws IOException
{
    BoolQueryBuilder query = QueryBuilders.boolQuery();
    for (Map.Entry entry : allRequestParams.entrySet()) {
        query.should(QueryBuilders.fuzzyQuery(entry.getKey(), entry.getValue()));
    }

    SearchResponse results = esClient.prepareSearch("nyc_visionzero")
        .setTypes("logs")
        .setQuery(query)
        .execute()
        .actionGet();

    SearchHits hits = results.getHits();
    hits.writeTo(response.getOutputStream());
}

但是最后一行有一个编译错误,因为两个OutputStream不兼容 . 所以我的问题是,将Elasticsearch的结果连接到Spring的响应中的最简单方法是什么?

3 回答

  • 1

    您可以更改搜索方法的签名以返回String,然后直接将结果作为有效JSON返回,而不是尝试写入响应输出流 . 就像是:

    @RequestMapping(value = "/search/{index:.*}", method = RequestMethod.GET)
    public String search(@PathVariable String index, @RequestParam Map allRequestParams, HttpServletResponse response)
        throws IOException
    {
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        for (Map.Entry entry : allRequestParams.entrySet()) {
            query.should(QueryBuilders.fuzzyQuery(entry.getKey(), entry.getValue()));
        }
    
        SearchResponse results = esClient.prepareSearch("nyc_visionzero")
            .setTypes("logs")
            .setQuery(query)
            .execute()
            .actionGet();
    
        SearchHits hits = results.getHits();
    
        // Replacing hits.writeTo(response.getOutputStream()); below
        StringBuilder builder = new StringBuilder();
        SearchHit[] hitsDatas = hits.hits();
        int length = hitsDatas.length;
        builder.append("[");
        for (int i = 0; i < length; i++) {
           if (i == length - 1) {
              builder.append(hitsDatas[i].getSourceAsString());
           } else {
              builder.append(hitsDatas[i].getSourceAsString());
              builder.append(",");
           }
        }
        builder.append("]");
        return builder.toString();
    }
    
  • -1

    我自己设法找到了解决方案:

    @RequestMapping(value = "/search/{index:.*}", method = RequestMethod.GET)
    public void search(@PathVariable String index, @RequestParam Map<String, String> allRequestParams, HttpServletResponse response)
        throws IOException
    {
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        for (Map.Entry<String, String> entry : allRequestParams.entrySet()) {
            query.should(QueryBuilders.fuzzyQuery(entry.getKey(), entry.getValue()));
        }
    
        SearchResponse results = esClient.prepareSearch("nyc_visionzero")
            .setTypes("logs")
            .setQuery(query)
            .execute()
            .actionGet();
    
        SearchHits hits = results.getHits();
    
        ServletOutputStream os = response.getOutputStream();
        XContentBuilder builder = XContentFactory.jsonBuilder(os);
        results.toXContent(builder, ToXContent.EMPTY_PARAMS);
        builder.close();
        os.close();
    }
    
  • 1
    @RequestMapping(value = "/search/{index:.*}", method = RequestMethod.GET)
    public ResponseEntity<?> search(@PathVariable String index, @RequestParam Map allRequestParams)
    {
    BoolQueryBuilder query = QueryBuilders.boolQuery();
    for (Map.Entry entry : allRequestParams.entrySet()) {
        query.should(QueryBuilders.fuzzyQuery(entry.getKey(), entry.getValue()));
    }
    
    SearchResponse results = esClient.prepareSearch("nyc_visionzero")
        .setTypes("logs")
        .setQuery(query)
        .execute()
        .actionGet();
    
    SearchHits hits = results.getHits();
    return new ResponseEntity<>(hits , HttpStatus.OK);
    }
    

    使用ResponseEntity类,您可以返回任何响应,而无需关心您的结果类型 .

相关问题