【问题标题】:How to wire the results of Elasticsarch into Spring's REST API reponse如何在 Spring REST API 响应中连接 Elasticsearch 的结果
【发布时间】:2017-12-20 00:58:53
【问题描述】:

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

我希望这样的事情会起作用:

@RequestMapping(value = "/search/{index:.*}", method = RequestMethod.GET) 公共无效搜索(@PathVariable 字符串索引,@RequestParam 映射 allRequestParams,HttpServletResponse 响应) 抛出 IOException { BoolQueryBuilder 查询 = QueryBuilders.boolQuery(); for (Map.Entry entry : allRequestParams.entrySet()) { query.should(QueryBuilders.fuzzyQuery(entry.getKey(), entry.getValue())); } SearchResponse 结果 = esClient.prepareSearch("nyc_visionzero") .setTypes("日志") .setQuery(查询) 。执行() .actionGet(); SearchHits 命中 = results.getHits(); hits.writeTo(response.getOutputStream()); }

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

【问题讨论】:

    标签: java spring elasticsearch


    【解决方案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();
    }
    

    【讨论】:

      【解决方案2】:
      @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 类,您可以返回任何响应,而无需关心您的结果类型。

      【讨论】:

      • 谢谢,但它不起作用。我认为它与 Jackson 或其他东西有一些问题,并导致一些运行时错误。
      【解决方案3】:

      您可以更改搜索方法的签名以返回字符串,然后直接将结果作为有效 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();
      }
      

      【讨论】:

      • 谢谢,但我找到了更好的解决方案。我会在几秒钟内发布它。
      猜你喜欢
      • 1970-01-01
      • 2020-11-09
      • 2018-05-22
      • 2017-09-19
      • 2020-02-24
      • 2014-08-24
      • 2021-05-26
      • 1970-01-01
      • 2016-05-01
      相关资源
      最近更新 更多