【问题标题】:spring-data-elasticsearch searching through different enttities/indiciesspring-data-elasticsearch 搜索不同的实体/索引
【发布时间】:2015-09-22 21:51:00
【问题描述】:

我需要提供允许用户搜索许多不同的域元素并将结果作为组合列表查看的功能。因此,在 UI 中,他只需填写一个文本字段即可检索结果。

为了可视化,假设我在域中有 3 个实体:

@Document(indexName="car") 
public class Car { 
  private int id;
  private String type;
} 
@Document(indexName="garage")
public class Garage{ 
  private int id;
  private String address;
} 
@Document(indexName="shop")
public class Shop{ 
  private int id;
  private String name;
}

现在我想我可以达到这样的要求:

...
@Inject
    private ElasticsearchTemplate elasticsearchTemplate;
...    
@RequestMapping(value = "/_search/all/{query}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public List<?> search(@PathVariable String query) {
     SearchQuery searchQuery = new NativeSearchQueryBuilder()
       .withQuery(queryString(query))
       .withIndices("car", "garage", "shop")
       .build();

    //THIS WORKS
    elasticsearchTemplate.queryForIds(searchQuery);

    //THIS THROWS ERROR ABOUT WRONG INDEXES
    return elasticsearchTemplate.queryForPage(searchQuery, GlobalSearchDTO.class, new GlobalSearchResultMapper()).getContent();
    }
...
    class GlobalSearchDTO {
        public Long id;
        public String type;
        public Object obj;
    }
 ...  

但是当调用第二个函数 - 负责返回实际文档的函数时,会抛出以下异常:

无法识别索引名称。 GlobalSearchDTO 不是文档。制作 确保使用 @Document(indexName="foo")

注释文档类

我尝试将任何域实体作为类参数传递,但我只从相应索引中检索元素,而不是全部。例如调用:

return elasticsearchTemplate.queryForPage(searchQuery, Shop.class, new GlobalSearchResultMapper()).getContent();

仅从“商店”索引中检索元素。似乎由于某种原因没有使用动态提供的索引。

所以问题是:是否可以检索这样的数据?为什么指定 '.withIndices("car", "garage", "shop")' 还不够?

也许我应该考虑其他解决方案,例如:

  1. 在循环中搜索索引(一个接一个),连接结果并按分数排序

  2. 使用“globalsearch”索引创建单独的 GlobalSearch 实体
    并在那里复制数据

提前致谢!

克日什托夫

【问题讨论】:

  • This,诚然,旧的线程状态在 14 年未实现,但可能仍然如此。 1和2肯定会工作!希望我能提供更多帮助,但也许该线程至少会有所帮助。
  • 感谢丹尼尔的反馈,我已经认真阅读了你在发布这个帖子之前提到的主题(也许我应该提到这个问题),我希望它已经实施到现在。好吧,我想现在我会选择第一种选择。我知道它会比第二个慢,但将来它可以通过所需的方法轻松更改 - 搜索多个指标。

标签: elasticsearch spring-data spring-data-elasticsearch


【解决方案1】:

我已设法为我的问题找到合适的解决方法。事实证明,当使用“滚动”和“扫描”功能时,会使用动态提供的索引,这意味着查询按预期工作。解决方案代码:

 @RequestMapping(value = "/_search/all/{query}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public List<?> search(@PathVariable String query) {
       SearchQuery searchQuery = new NativeSearchQueryBuilder()
         .withQuery(queryString(query))
         .withIndices("car", "garage", "shop")
         .withPageable(new PageRequest(0,1))
         .build();

         String scrollId = elasticsearchTemplate.scan(searchQuery, 1000, false);
         List<GlobalSearchDTO> sampleEntities = new ArrayList<GlobalSearchDTO>();
         boolean hasRecords = true;
         while (hasRecords){
             Page<GlobalSearchDTO> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultMapper());
             if(page != null) {
                 sampleEntities.addAll(page.getContent());
                 hasRecords = page.hasNext();
             }
             else{
                 hasRecords = false;
             }
         }
         return sampleEntities;
    }

}

在 ResultMapper 类中:

...
for (SearchHit hit : response.getHits()) { 
    switch(hit.getIndex()) {
                case "car": //map to DTO
                case "shop": //map to DTO
                case "garage": //map to DTO
                }
}   
...  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    • 2016-04-09
    • 2016-01-02
    • 2018-08-01
    • 2014-05-30
    • 1970-01-01
    相关资源
    最近更新 更多