spring-data-mongo 实现aggregation

摘要

mongo aggregation是mongo 的一个轻量级的map-reduce框架,可以实现一些count,sum,groupby的聚合。本身的意义就在于减少查询次数,将原本需要客户端的多次查询能够整合到db端的基于pipeline的查询。这样带来的好处就是减少请求数据库次数,坏处就是这个查询占用的数据库内存大,时间查,有可能拖垮其他查询。这个在本篇文章不讨论。

概述

常用的阶段函数

  • $match: 就是where查询

  • $group : 就是group by

  • $project:添加新字段/重置已有字段,比如group阶段的key值会变成_id就需要

  • $unwind :将数组拆分为几个字段

  • $sort 排序

  • $limit 限制条数

  • $skip 跳过条数

例子

  1. java 配置 mongo 连接

    @Configuration
    @EnableMongoRepositories(basePackages = "com.fs.mongo.dao")
    public class MongoConfig extends AbstractMongoConfiguration {
    
        @Bean
        public MongoDbFactory mongoDbFactory() throws UnknownHostException {
            MongoClientOptions options = new MongoClientOptions.Builder().connectionsPerHost(8).build();
            return new SimpleMongoDbFactory(new MongoClient("localhost",options ),"test");
        }
        // 默认数据库会生成_class字段,需要更改mappingMongoConverter的typeMappper属性值
        @Bean
        public MongoTemplate mongoTemplate() throws Exception {
            return new MongoTemplate(mongoDbFactory(),mappingMongoConverter());
        }
    
        protected String getDatabaseName() {
            return "test";
        }
    
        @Bean
        public Mongo mongo() throws Exception {
            return new MongoClient();
        }
    
        @Bean
        @Override
        public MappingMongoConverter mappingMongoConverter() throws Exception {
            MappingMongoConverter converter = new         MappingMongoConverter(mongoDbFactory(),this.mongoMappingContext());
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
            return converter;
        }
    }
  2. 基于mongoTemplate 发送aggregate请求

    @Component
    public class PostDb {
        @Autowired
        private MongoTemplate mongoTemplate;
    
        public PostDb(MongoTemplate mongoTemplate) {
            this.mongoTemplate = mongoTemplate;
        }
        public List<Post> getPeopleAggregationByCategory(long userId) {
            MatchOperation match = Aggregation.match(new Criteria("userId").is(userId));
            GroupOperation group  = Aggregation.group("category").count().as("total");
            // 注group key category会映射成_id,所以要利用project阶段映射回category
            ProjectionOperation project =  Aggregation.project("total").and("_id").as("category");
            Aggregation aggregation = Aggregation.newAggregation(match,group,project);
            AggregationResults<Post> results = mongoTemplate.aggregate(aggregation,"post",Post.class);
            return results.getMappedResults();
        }
    }

完整代码:
https://github.com/FS1360472174/nosql-mongo/tree/master/project/sample/sample-mongo-aggregation

扫码关注NoSQL开发公众号,第一时间接收文章推送
这里写图片描述

猜你喜欢

转载自blog.csdn.net/fs1360472174/article/details/74081487