LookupOperation MongoTemplate 来联表查询分页 以table2的字段作为排序字段
时间: 2023-05-27 18:01:39 浏览: 142
一个示例代码:
```
// 定义输出结果的DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Table1Table2Dto {
private String id;
private String name;
private String table2Name;
private Integer age;
}
// 定义Table1的索引
@Document(collection = "table1")
@CompoundIndex(def = "{'name': 1, 'age': -1}")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Table1 {
@Id
private String id;
private String name;
private Integer age;
}
// 定义Table2的索引
@Document(collection = "table2")
@CompoundIndex(def = "{'name': 1}")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Table2 {
@Id
private String id;
private String name;
}
// 实现分页联表查询方法
public Page<Table1Table2Dto> findTable1JoinTable2(String table2Name, int pageNum, int pageSize, String sortField, Sort.Direction sortDirection) {
// 构建查询条件
Criteria criteria = Criteria.where("name").regex(table2Name);
LookupOperation lookupOperation = LookupOperation.newLookup().
from("table2")
.localField("name")
.foreignField("name")
.as("table2");
// 构建排序条件
Sort sort = Sort.sort(Table2.class)
.by(sortField)
.with(sortDirection);
AggregationOperation sortOperation = Aggregation.sort(sort);
// 获取总记录数
Aggregation countAggregation = Aggregation.newAggregation(
Aggregation.match(criteria),
lookupOperation,
Aggregation.unwind("table2"),
Aggregation.count().as("totalCount")
);
AggregationResults<BasicDBObject> countResults = mongoTemplate.aggregate(countAggregation, Table1.class, BasicDBObject.class);
int totalCount = countResults.getUniqueMappedResult().getInt("totalCount");
// 构建分页、联表查询的Aggregation
int skip = (pageNum - 1) * pageSize;
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(criteria),
lookupOperation,
Aggregation.unwind("table2"),
sortOperation,
Aggregation.skip(skip),
Aggregation.limit(pageSize),
Aggregation.project()
.and("id").as("_id")
.and("name").as("name")
.and("table2.name").as("table2Name")
.and("age").as("age")
);
AggregationResults<Table1Table2Dto> results = mongoTemplate.aggregate(aggregation, Table1.class, Table1Table2Dto.class);
List<Table1Table2Dto> list = results.getMappedResults();
// 构建分页对象
return new PageImpl<>(list, PageRequest.of(pageNum - 1, pageSize, sort), totalCount);
}
```
代码解释:
1. 定义了3个类:Table1,Table2和Table1Table2Dto。Table1和Table2都是要查询的表,Table1Table2Dto是用来输出最终查询结果的DTO。
2. Table1和Table2都定义了索引,以便优化查询速度。Table1的索引使用了name和age作为联合索引,Table2的索引使用了name作为唯一索引。
3. 实现了分页联表查询方法findTable1JoinTable2,输入参数包括查询条件(table2Name)、页码(pageNum)、每页数量(pageSize)、排序字段(sortField)和排序方式(sortDirection)。
4. 方法中需要进行如下几个操作:
* 构建查询条件:使用Criteria类构建查询条件,使用LookupOperation类进行联表查询。
* 构建排序条件:使用Sort类构建排序条件,使用Aggregation.sort()方法将排序条件作为AggregationOperation对象。
* 获取总记录数:使用聚合管道,查询符合条件的记录数量。
* 构建联表查询的聚合管道:使用Aggregation对象构建查询管道,包括查询条件、联表查询、排序、分页、投影等等操作。
* 最终生成的结果是Page<Table1Table2Dto>对象,包括查询结果、分页信息和总记录数等等数据。
使用示例:
```
Page<Table1Table2Dto> pageResult = findTable1JoinTable2("table2_name_like", 1, 10, "table2Name", Sort.Direction.DESC);
for (Table1Table2Dto item : pageResult.getContent()) {
System.out.println(item.getId() + "," + item.getName() + "," + item.getAge() + "," + item.getTable2Name());
}
```
其中,"table2_name_like"为Table2中name字段的模糊匹配查询条件,1为页码,10为每页数量,"table2Name"为排序字段,Sort.Direction.DESC为排序方式。输出结果类似:
```
611115ec7deb24ccbe14cf62,Lincoln,23,Lincoln23
611115ec7deb24ccbe14cf63,Lincoln,25,Lincoln25
611115ec7deb24ccbe14cf69,Lincoln,24,Lincoln24
```
阅读全文