Как правильно использовать API SearchAfter? - PullRequest
0 голосов
/ 28 октября 2019

Я недавно работаю сasticsearch и у меня такой вопрос. У меня есть миллион документов в индексе, и я хочу получить более 10_000. Для этого я могу использовать scroll API или SearchAfter API. Я понял, как работает scroll api, но у меня есть некоторые проблемы с SearchAfter.

Вот мой метод SearchSourceBuilder:

public SearchRequest buildRequest(SearchDistanceParameters args) {
    final SearchSourceBuilder searchSourceBuilder = prepareSearchSourceBuilder(args);
    final SearchRequest searchRequest = new SearchRequest();
    return searchRequest.source(searchSourceBuilder);
}

private SearchSourceBuilder prepareSearchSourceBuilder(SearchDistanceParameters searchDistanceParameters) {
    final FieldSortBuilder fieldSortBuilder = new FieldSortBuilder("_id").order(SortOrder.ASC);
    final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    final GeoDistanceQueryBuilder geoDistanceQueryBuilder = geoDistanceQuery(GeoLocationModelFieldName.LOCATION.name().toLowerCase());
    geoDistanceQueryBuilder.point(searchDistanceParameters.getLatitude(), searchDistanceParameters.getLongitude());
    geoDistanceQueryBuilder.distance(searchDistanceParameters.getDistance(), DistanceUnit.KILOMETERS);
    searchSourceBuilder.query(geoDistanceQueryBuilder);
    searchSourceBuilder.sort(fieldSortBuilder);
    searchSourceBuilder.searchAfter();
    return searchSourceBuilder;
}

Здесь я делаю сортировку перед searchAfter ()как упомянуто в SearchAfter API doc.

Здесь я отправляю свой запрос в ElasticSearch:

public SearchResponse sendRequestToElastic(SearchDistanceParameters args) throws IOException {
    SearchRequest searchRequest = searchByDistanceRequestBuilder.buildRequest(args);
    return elasticDao.search(searchRequest, RequestOptions.DEFAULT); // standard RestHighLevelClient.search method inside elasticDao.
}

И, наконец, я пытаюсь получить мои объекты из SearchResponse:

public List<GeoPointsFromElasticSearchResponse> searchByDistance(SearchDistanceParameters searchDistanceParameters) {
        final SearchResponse searchResponse = searchRepository.searchByDistance(searchDistanceParameters);
        return getGeoPointsFromElasticSearchResponses(searchResponse);
    }

private List<GeoPointsFromElasticSearchResponse> getGeoPointsFromElasticSearchResponses(SearchResponse searchResponse) {
        SearchHit[] hits = searchResponse.getHits().getHits();
        return Arrays.stream(hits)
                .map(hit -> {
                    final GeoPointsFromElasticSearchResponse geoPointsFromElasticSearchResponse = new GeoPointsFromElasticSearchResponse();
                    final Map<String, Object> sourceMap = hit.getSourceAsMap();
                    final Map map = (Map) sourceMap.get(GeoLocationModelFieldName.LOCATION.name().toLowerCase());
                    geoPointsFromElasticSearchResponse.setLatitude((Double) map.get("lat"));
                    geoPointsFromElasticSearchResponse.setLongitude((Double) map.get("lon"));
                    log.info("Sorted hits: {}", hit.getSortValues());
                    return geoPointsFromElasticSearchResponse;
                }).collect(Collectors.toList());
    }

Но у меня есть только 10_000 объектов. Кажется, я делаю что-то не так в последней части. Что я делаю неправильно? Как правильно использовать SearchAfter API в Java?

1 Ответ

0 голосов
/ 28 октября 2019

Хорошо, API поиска не возвращает все документы в одном запросе, поведение аналогично нумерации страниц.

Вы должны передать аргумент для поиска после: https://www.elastic.co/guide/en/elasticsearch/reference/6.7/search-request-search-after.html

В соответствии сconstructor: searchSourceBuilder.searchAfter (new Object [] {sortAfterValue});

Значение, которое вы хотите установить, - это значение, возвращаемое первым поисковым запросом (hit => getAt (lastIndex) => getSortValues ​​())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...