elasticsearch,Java,Spring,Spring Boot,elasticsearch" /> elasticsearch,Java,Spring,Spring Boot,elasticsearch" />

Java Spring弹性搜索:如何通过映射到不同对象跨多个索引进行搜索

Java Spring弹性搜索:如何通过映射到不同对象跨多个索引进行搜索,java,spring,spring-boot,elasticsearch,Java,Spring,Spring Boot,elasticsearch,首先很抱歉,如果有人问这个问题,我已经到处找了,没有结果 基本上我有一个ES实例,它有3个索引。索引的数据/映射是从我的java POJO生成的。现在我可以单独搜索每个索引,并将其映射回给定的Pojo/类 然而,当我想一次搜索3个索引并将搜索命中映射到正确的Pojo时,我完全不知所措 例如,我目前是如何搜索映射到我拥有的UserProfile对象的单个索引的: public Iterable<UserProfile> fetchUserSearchSuggestions(St

首先很抱歉,如果有人问这个问题,我已经到处找了,没有结果

基本上我有一个ES实例,它有3个索引。索引的数据/映射是从我的java POJO生成的。现在我可以单独搜索每个索引,并将其映射回给定的Pojo/类

然而,当我想一次搜索3个索引并将搜索命中映射到正确的Pojo时,我完全不知所措

例如,我目前是如何搜索映射到我拥有的UserProfile对象的单个索引的:

    public Iterable<UserProfile> fetchUserSearchSuggestions(String query, Integer page, Integer size) {

        PageRequest pageRequest = PageRequest.of(page, size);

        QueryBuilder queryBuilder = QueryBuilders.boolQuery().should(new WildcardQueryBuilder("displayName", query + "*"))
                .should(new WildcardQueryBuilder("name", query + "*"));

        Query searchQuery = new NativeSearchQueryBuilder()
                .withFilter(queryBuilder)
                .withPageable(pageRequest)
                .build();

        SearchHits<UserProfile> searchSuggestions =
                elasticsearchOperations.search(searchQuery,
                        UserProfile.class,
                        IndexCoordinates.of(elasticUserIndex));

        List<UserProfile> suggestions = new ArrayList<>();

        searchSuggestions.getSearchHits().forEach(searchHit -> {
            suggestions.add(searchHit.getContent());
        });
        long totalCount = searchSuggestions.getTotalHits();
        Page<UserProfile> resultPage = PageableExecutionUtils.getPage(
                suggestions,
                pageRequest,
                () -> totalCount);
        return resultPage;
    }
public Iterable fetchUserSearchSuggestions(字符串查询、整数页面、整数大小){
PageRequest PageRequest=PageRequest.of(页面,大小);
QueryBuilder QueryBuilder=QueryBuilders.boolQuery().should(新的通配符QueryBuilder(“displayName”,query+“*”))
.should(新的WildcardQueryBuilder(“名称”,查询+“*”));
Query searchQuery=new NativeSearchQueryBuilder()
.带过滤器(queryBuilder)
.withPageable(pageRequest)
.build();
搜索点击搜索建议=
elasticsearchOperations.search(搜索查询,
UserProfile.class,
(elasticUserIndex)的索引协调性;
列表建议=新建ArrayList();
searchSuggestions.getSearchHits().forEach(searchHit->{
添加(searchHit.getContent());
});
long totalCount=searchSuggestions.getTotalHits();
Page resultPage=PageableExecutionLS.getPage(
建议,
页面请求,
()->总计数);
返回结果页;
}
同样,我的问题是,如果我想一次搜索所有索引,比如通用搜索,并将用户结果映射到UserProfile类,等等,那么对于我拥有的每个不同对象,我该怎么做呢


非常感谢阅读

您知道多搜索请求吗

假设我们有一个具有这种结构的类请求:

class Request {
    private String index;
    private String field;
    private String value;
}
  • 索引-弹性搜索索引
  • 字段-我们正在查看的字段
  • 值-字段值
跨多个索引的搜索将如下所示

   public MultiSearchResponse find(List<Request> requests) throws IOException {
    
    MultiSearchRequest multiSearchRequest = new MultiSearchRequest();

    for (Request req : requests){
        QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchBoolPrefixQuery(req.field, req.value));

        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.size(1);
        builder.query(queryBuilder);

        SearchRequest searchRequest = new SearchRequest();
        searchRequest.searchType(SearchType.DFS_QUERY_THEN_FETCH);
        searchRequest.indices(req.index);
        searchRequest.source(builder);

        multiSearchRequest.add(searchRequest);
    }

    return restHighLevelClient.msearch(multiSearchRequest, RequestOptions.DEFAULT);
}
public static List<SensorValueElasticsearch> parse(MultiSearchResponse response) {

    List<SensorValueElasticsearch> values = new ArrayList<>();
    
    for (MultiSearchResponse.Item item : response.getResponses()){
        if (item.getResponse().getHits().getTotalHits().value > 0){
            values.addAll(convertToList(item.getResponse()));
        }
    }
    return values;
}

public static List<SensorValueElasticsearch> convertToList(SearchResponse response) {
    SearchHit[] res = response.getHits().getHits();

    List<SensorValueElasticsearch> list = new LinkedList<>();

    for (SearchHit sh : res) {

        SensorValueElasticsearch object = null;
        try {
            object = OBJECT_MAPPER.readValue(sh.getSourceAsString(), SensorValueElasticsearch.class);
        } catch (JsonProcessingException e) {
            LOGGER.warn("Error while convert SearchResponse to SensorValueElasticsearch", e);
        }

        list.add(object);
    }

    return list;
}

您能否在每个索引中添加一个表示文档类型(可能是字符串值)的字段,并在获取结果时检查此字段的值并相应地将其映射到类?我可以,但那里已经有很多数据需要更改。我看到过类似的情况,但我找不到Java等价物。感谢您的回复,我遇到的问题是,如果有三个类代表这三个索引,该怎么办。如何将响应命中映射到相应的类。再次感谢,尽管我的答案是正确的
        ObjectA a = null;
        ObjectB b = null;

        try {
            return OBJECT_MAPPER.readValue(sh.getSourceAsString(), ObjectA.class);
        } catch (JsonProcessingException e) {
            // ignore
        }

        try {
            return OBJECT_MAPPER.readValue(sh.getSourceAsString(), ObjectB.class);
        } catch (JsonProcessingException e) {
            // ignore
        }

        throw new IllegalArgumentException("Unknown class");