本例基于spring-data-mongodb 1.10.4 版本
-- 分页
@Repository
public interface AttachmentDao extends MongoRepository<Attachment, String> {
List<Attachment> findByTypeAndName(String type, String name);
}
public Page<Attachment> findAttachmentPage(QueryAttachmentReq req) {
Sort.Order order = new Sort.Order(Sort.Direction.DESC, "uploadTime");
Sort sort = new Sort(order);
PageRequest pageRequest = new PageRequest(req.getPageNum() - 1, req.getPageSize(), sort);
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式:模糊查询
.withIgnoreCase(true) //改变默认大小写忽略方式:忽略大小写
.withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains()) //采用“包含匹配”的方式查询
.withIgnorePaths("pageNum", "pageSize"); //忽略属性,不参与查询;
Example<Attachment> example = Example.of(req, matcher);
return attachmentDao.findAll(example, pageRequest);
}
-- 分组
private Document getDocument(){
return AnnotationUtils.findAnnotation(KreddoTaskCollection.class, Document.class);
}
private DBCollection getDBCollection(){
return mongoTemplate.getCollection(getDocument().collection());
}
public List<TaskCollectionGroupInfo> selectMaxClientCodeGroupByProductType(List<Long> userIdList){
/* Aggregation aggregation = Aggregation.newAggregation(
KreddoTaskCollection.class,
Aggregation.match(Criteria.where("user_id").in(userIdList)),
Aggregation.group("user_id","product_type")
.max("dpd").as("maxDpd")
.sum("amount_due").as("sumAmountDue"),
Aggregation.project("maxDpd","sumAmountDue").and("user_id").as("userId")
.and("product_type").as("productType")
);
aggregation.withOptions()
// log.info("nosql:{}",aggregation);
Document document = AnnotationUtils.findAnnotation(KreddoTaskCollection.class, Document.class);
AggregationResults aggregationResults=mongoTemplate.aggregate(aggregation,document.collection(),TaskCollectionGroupInfo.class);
return aggregationResults.getMappedResults();*/
List<DBObject> pipeline = new ArrayList<>();
GroupOperation group = Aggregation.group("user_id","product_type").max("dpd").as("maxDpd")
.sum("amount_due").as("sumAmountDue");
MatchOperation match = Aggregation.match(Criteria.where("user_id").in(userIdList));
pipeline.add(match.toDBObject(Aggregation.DEFAULT_CONTEXT));
pipeline.add(group.toDBObject(Aggregation.DEFAULT_CONTEXT));
AggregationOptions build = AggregationOptions.builder()
.allowDiskUse(true)
.outputMode(AggregationOptions.OutputMode.CURSOR)//指定聚合的输出格式为CURSOR
.build();
Cursor cursor = getDBCollection().aggregate(pipeline,build);
List<TaskCollectionGroupInfo> result = new ArrayList<>();
TaskCollectionGroupInfo row;
while(cursor.hasNext()) {
DBObject object = cursor.next();
row=JSON.parseObject(JSON.toJSONString(object),TaskCollectionGroupInfo.class);
BasicBSONObject obj=(BasicBSONObject)object.get("_id");
row.setUserId(MapUtils.getLong(obj,"user_id"));
row.setProductType(MapUtils.getString(obj,"product_type"));
result.add(row);
}
return result;
}
-- 批量更新
public CommandResult batchUpdateClientCodeAndTotalAmount(List<TaskCollection> list){
DBCollection dbCollection=getDBCollection();
DBObject command = new BasicDBObject();
command.put("update", getDocument().collection());
List<BasicDBObject> updateList = new ArrayList<>();
BasicDBObject update;
for(TaskCollectionk:list){
update = new BasicDBObject();
update.put("q",new Query().addCriteria(Criteria.where("user_id").is(k.getUser_id())).getQueryObject());
update.put("u",new Update().set("client_code",k.getClient_code()).set("total_amount_due",k.getTotal_amount_due()).getUpdateObject());
update.put("multi", true);
updateList.add(update);
}
command.put("updates", updateList);
command.put("ordered", false);
CommandResult commandResult = dbCollection.getDB().command(command);
return commandResult;
}
总结下遇到的问题
1 PageRequest 分页page从0开始,所以传入页码需要减去1
2 默认保存数据会插入_class字段,若想去掉需要做额外操作
3 Aggregation 分组获取在高版本之后需要使用游标获取,不然会报错
@Configuration
@Slf4j
public class MongoConfig {
@Bean
public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
try {
mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
} catch (NoSuchBeanDefinitionException e) {
log.warn("MappingMongoConverter setCustomConversions失败", e.getBeanName());
}
// Don't save _class to mongo
mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
return mappingConverter;
}
}