MongoDB Java驱动程序3.x:如何将allowDiskUse = true传递给aggregate()方法?
我正在使用mongo-java-driver 3.0.2 。
我有一个方法,使用MongoCollection.aggregate(List pipeline)
来排序和限制:
private static MongoIterable selectTop(int n) { BasicDBObject sortFields = new BasicDBObject("score", -1); BasicDBObject sort = new BasicDBObject("$sort", sortFields); BasicDBObject limit = new BasicDBObject("$limit", n); List pipeline = new ArrayList(); pipeline.add(sort); pipeline.add(limit); return playersCollection.aggregate(pipeline); }
当n
很大时,它失败了:
com.mongodb.MongoCommandException: Command failed with error 16820: 'exception: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation. Pass allowDiskUse:true to opt in.'
我发现MongoDB shell提供了一个方法db.collection.aggregate(pipeline, options)
( link ),其中options
可以包含allowDiskUse
字段。
我在Java API中找不到与此相当的东西。 尽管存在AggregationOptions类,但MongoCollection
类不提供aggregate(List pipeline, AggregationOptions options)
方法。
这仍然适用于3.0.3驱动程序:
MongoClient client = new MongoClient(new ServerAddress("127.0.0.1", 27017)); DB test = client.getDB("test"); DBCollection sample = test.getCollection("sample"); List aggregationQuery = Arrays. asList( new BasicDBObject("$sort",new BasicDBObject("score",-1)), new BasicDBObject("$limit",1) ); System.out.println(aggregationQuery); Cursor aggregateOutput = sample.aggregate( aggregationQuery, AggregationOptions.builder() .allowDiskUse(true) .build() ); while ( aggregateOutput.hasNext() ) { DBObject doc = aggregateOutput.next(); System.out.println(doc); }
当然你也可以使用更新的类:
MongoClient client = new MongoClient(new ServerAddress("192.168.2.4", 27017)); MongoDatabase db = client.getDatabase("test"); MongoCollection collection = db.getCollection("sample"); AggregateIterable result = collection.aggregate(Arrays.asList( new BasicDBObject("$sort", new BasicDBObject("score", -1)), new BasicDBObject("$limit", 1) )).allowDiskUse(true); MongoCursor cursor = result.iterator(); while (cursor.hasNext()) { Document doc = cursor.next(); System.out.println(doc); }
因此,MongoCollection上的.aggregate()
返回一个AggregateIterable
类实例,该实例具有.allowDiskuse()
方法以及其他设置聚合选项的方法。