springElasticSearch:如何通过Map到不同对象跨多个索引进行搜索

xdyibdwo  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(279)

回答此问题可获得+50声望奖励。赏金宽限期已经结束。菲尔班正在寻找一个标准答案
嗨,我需要看看如何在ElasticSearch中搜索所有索引,并将它们绑定到不同的javapojo
首先很抱歉,如果有人问这个问题,我已经到处找了,没有结果。
基本上我有一个es示例,它有3个索引。索引的数据/Map是从我的javapojo生成的。现在我可以单独搜索每个索引并将其Map回给定的pojo/类。
然而,当我想一次搜索3个索引并将搜索结果Map到正确的pojo时,我完全不知所措。
例如,下面是我当前如何搜索Map到我拥有的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;
    }

我的问题是,如果我想一次搜索所有索引,比如通用搜索,并将用户结果Map到userprofile类,等等,对于我拥有的每个不同的对象,我该怎么做呢。
非常感谢您的阅读

eyh26e7m

eyh26e7m1#

你知道多重搜索的要求吗?
假设我们有这样一个结构的类请求:

class Request {
    private String index;
    private String field;
    private String value;
}

索引-elasticsearch索引
我们正在寻找的领域
值-字段值
跨多个索引的搜索如下所示

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;
}

在你之前的情况下 OBJECT_MAPPER.readValue 必须检查找到的对象类型,或使用try-catch块写入return,如下所示:

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");

相关问题