MongoDB里面有两个Collection,一个是cutting_tool_template(刀具模板),一个是cutting_tool(刀具),每把刀具隶属于一个模板,因此一个模板拥有多把刀具。现在页面需要展示该刀具模板有多少把刀具。
有很多种实现方法: 第一:把刀具集合作为模板的一个列表;
第二:模板增加一个变量(tool_count),增加一把刀具则+1,删除一把刀具则-1;
第三:每次查询模板数据的时候,联合查询刀具表,进行一个mysql里面的count操作。
这里采用了第三种方法。通过cutting_tool.template._id与cutting_tool.template_id进行关联。
MongoDB通过lookup函数来实现两个collection的联合查询。描述如下:
1 2 3 4 5 6 7 8 9 10 11 12 /** * from: The target collection. 目标集合,即本案例中的[刀具]表 * localField: The local join field. 本地联合变量:即本案例中的[模板表]的ID * foreignField: The target join field. 目标联合变量,即本案例中的[刀具表]的模板ID * as: The name for the results. 联合查询后结果的名称 */ { from: 'cutting_tool', localField: '_id', foreignField: 'template_id', as: 'tool_array' }
参考代码一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @Test public void testAggregation ( ) { Query query = new Query(); query.addCriteria(Criteria.where("type_of_tool_body" ).is( "Centerdrill" )); AggregationOperation match = (value) -> new Document("$match" , query.getQueryObject() ); AggregationOperation addFields = (AggregationOperationContext aggregationOperationContext) -> { DBObject dbObject = new BasicDBObject("tool_count" , new BasicDBObject("$size" , "$tool_array" )); return new Document( new BasicDBObject("$addFields" , dbObject) ); }; long skipNum = 0L ; int limitNum = 3 ; Aggregation aggregation = Aggregation.newAggregation( match, Aggregation.skip( skipNum ), Aggregation.limit( limitNum ), Aggregation.lookup("cutting_tool" , "_id" , "template_id" , "tool_array" ), addFields ); AggregationResults<CuttingToolTemplate> cutting_tool_template1 = mongoTemplate.aggregate(aggregation, "cutting_tool_template" , CuttingToolTemplate.class); for ( CuttingToolTemplate ctt : cutting_tool_template1.getMappedResults() ) { System.out.println("CTT-----------" + ctt ); } }
参考代码二: 实现功能与上述代码一致,只是用另外一种写法来实现。
这种写法更简单,配合MongoDB Compass 食用(自动生成Java版的Aggregation代码),更加方便。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Test public void testDoc2Bson ( ) { Query query = new Query(); query.addCriteria(Criteria.where("type_of_tool_body" ).is( "Centerdrill" )); Document queryDoc = query.getQueryObject(); int skipNum = 0 ; int limitNum = 3 ; List<Bson> bsons = new ArrayList<>(); bsons.add( match(queryDoc) ); bsons.add( skip(skipNum) ); bsons.add( limit(limitNum) ); bsons.add( lookup("cutting_tool" , "_id" , "template_id" , "tool_array" ) ); bsons.add( addFields(new Field("tool_count" , new Document("$size" , "$tool_array" ))) ); bsons.add( project(exclude("tool_array" )) ); MongoCollection<Document> cutting_tool_template = mongoTemplate.getCollection("cutting_tool_template" ); AggregateIterable<Document> aggregate = cutting_tool_template.aggregate(bsons); for ( Document doc : aggregate ){ CuttingToolTemplate o = mongoTemplate.getConverter().read( CuttingToolTemplate.class, doc); System.out.println("CTT: " + o); } }
简单做下备案,希望对你有用。