У меня есть критерии поиска, по которым я должен предоставить нумерацию результатов поиска вместе с общим количеством записей в коллекции. Предположим, что в коллекции из 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.