Агрегация MongoDB в Java: Как получить общее количество записей вместе с результатом разбивки на страницы? - PullRequest
1 голос
/ 08 ноября 2019

У меня есть критерии поиска, по которым я должен предоставить нумерацию результатов поиска вместе с общим количеством записей в коллекции. Предположим, что в коллекции из 10 записей я хочу получить только 5 записей вместе с общим количеством записей. Получив данные, я хочу запихнуть их в отдельный объект, имеющий свойства count и searchResult. Общее количество записей должно быть сопоставлено для подсчета и разбито на страницы записей для searchResult. Я применил агрегацию, и она работает хорошо, за исключением включения CountOperation и ProjectOperation. Когда я добавляю countOperation и ProjectOperation в агрегацию, он дает недопустимую ссылку "_id!"исключение. ожидаемый запрос будет выглядеть следующим образом.

   db.customer.aggregate([
{
  $facet:{
    searchResult:[{$match:{"name" : { "$regex" : "xyz", "$options" : "i" }}}],
    count: [{ $count: 'count' }]
  }
}

])

и результат будет таким:

   [
    {
      "searchResult":[{...},{...},{...}, ...],
      "count":[{"count":100}]
    }
   ]

Логика поиска:

public List<SampleSearchResult> findListByRequest(ListRequest queryParams, Class<T> clazz) {

    String collectionName = mongoTemplate.getCollectionName(clazz);
    MatchOperation matchOperation = getMatchOperation(queryParams);
    SortOperation sortOperation = getSortOperation(queryParams);
    SkipOperation skipOperation = Aggregation.skip((long) queryParams.getPageNumber() * queryParams.getSize());
    LimitOperation limitOperation = Aggregation.limit(queryParams.getSize());
            CountOperation countOperation = Aggregation.count().as("count");
    ProjectionOperation projectionOperation = getProjectionOperation();

    AggregationResults<SampleSearchResult> results = mongoTemplate
            .aggregate(Aggregation.newAggregation(matchOperation, sortOperation, skipOperation, limitOperation, countOperation, projectionOperation ), collectionName, SampleSearchResult.class);

    return (List<SampleSearchResult>) results.getMappedResults();
}

Логика операции проецирования

    private ProjectionOperation getProjectionOperation() {
    return Aggregation.project("count").and("_id").previousOperation();
}

Логика SortOperation:

private SortOperation getSortOperation(ListRequest listRequest) {
    // setting defaults
    if (StringUtils.isEmpty(listRequest.getSortBy())) {
        listRequest.setSortBy("_id");
        listRequest.setAsc(false);
    }
    Sort sort = listRequest.isAsc() ? new Sort(Direction.ASC, listRequest.getSortBy())
            : new Sort(Direction.DESC, listRequest.getSortBy());
    return Aggregation.sort(sort);
}

Логика MatchOperation:

private MatchOperation getMatchOperation(ListRequest listRequest) {
    Criteria criteria = new Criteria();
    // build match operation logic with listRequest parameters
    return Aggregation.match(criteria);
}

Результирующий объект, который будет содержать результат агрегирования

    public class SampleSearchResult {
private List<Object> searchResult;
private int count;
public List<Object> getSearchResult() {
    return searchResult;
}
public void setSearchResult(List<Object> searchResult) {
    this.searchResult = searchResult;
}
public int getCount() {
    return count;
}
public void setCount(int count) {
    this.count = count;
}

}

Мне нужно правильно написать CountOperation и ProjectionOperation для сопоставления данных с SampleSearchResult, но я не настолько эффективен, поскольку я новичок в операциях MongoDB.

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