1. 程式人生 > >spring-data-mongo 實現aggregation

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();
        }
    }

掃碼關注NoSQL開發公眾號,第一時間接收文章推送
這裡寫圖片描述