日常業務では、データベースの特定のフィールドに基づいて重複を排除する必要がある場合があります。その際、mongotemplate.findDistinctメソッドを使用できます。しかし、このメソッドを使用すると、ソート、ページネーション、総数の取得などの他のビジネス要件にうまく対応できません。ビジネスをより良く実現するために、mongo のパイプライン集約を使用できます。以下にコードを直接示します:
条件 + 重複排除 + ソート + ページネーション
public void group() {
int page = 1; //ページ番号
int size = 4; //ページサイズ
Criteria criteria = Criteria.where("num").lte(10);
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(criteria), //フィルタ条件
Aggregation.group("age") // 指定フィールドに基づいて重複を排除
.first("$$ROOT").as("document"), // ドキュメント全体を保持
Aggregation.replaceRoot("document"), // 保存されたドキュメントオブジェクトを出力ドキュメントとして使用
Aggregation.sort(Sort.by(Sort.Direction.ASC, "num")), // 指定フィールドでソート
Aggregation.skip((page - 1) * size), // 指定されたページ数をスキップ
Aggregation.limit(size)
);
AggregationResults<User> results = mongoTemplate.aggregate(aggregation, "user", User.class);
List<User> userList = results.getMappedResults();
Aggregation countAgg = Aggregation.newAggregation(
Aggregation.match(criteria), // フィルタ条件
Aggregation.group("age"), // 指定フィールドに基づいて重複を排除
Aggregation.count().as("total") // 重複排除後の総数を計算
);
AggregationResults<org.bson.Document> countResults = mongoTemplate.aggregate(countAgg, "user", org.bson.Document.class);
int total = 0;
if (!countResults.getMappedResults().isEmpty()) {
total = countResults.getMappedResults().get(0).getInteger("total");
}
System.out.println("クエリ結果");
System.out.println("現在は第" + page + "ページ");
userList.forEach(System.out::println);
System.out.println("総数は:" + total);
}
エンティティクラス
public class User {
private Integer num;
private String name;
private Integer age;
}
データベースデータ
実行結果