您的位置:首页技术文章
文章详情页

java - mongodb分片集群下,count和聚合统计问题

【字号: 日期:2024-01-18 14:17:41浏览:54作者:猪猪

问题描述

在mongodb分片集群下,直接用count统计会不准确,用聚合统计则可以

java - mongodb分片集群下,count和聚合统计问题

但是在java或mongodb客户端(非命令行)调用mongodb,使用聚合统计时,统计的结果和count同样不准确,请问大神们,我的代码如下,请大神指点,找不到原因!

@Testpublic void testCount() throws Exception { DynamicSqlParameter dsp = new DynamicSqlParameter(); long sT = System.currentTimeMillis(); MongoDatasource mongoDatasource = MongoDatasource.getInstance(mongoService.getDatasource()); DBCollection dbCollection = mongoDatasource.getDB().getCollection('dayFlow'); List arrayList = new ArrayList<>(); DBObject dbObject1 = new BasicDBObject(); dbObject1.put('usedDayFlow', 2); DBObject dbObject2 = new BasicDBObject(); dbObject2.put('_id', null); dbObject2.put('count', new BasicDBObject('$sum', 1)); arrayList.add(new BasicDBObject('$match', dbObject1)); arrayList.add(new BasicDBObject('$group', dbObject2)); System.out.println(JSON.serialize(arrayList)); AggregationOutput size = dbCollection.aggregate(arrayList); System.out.println(size.results()); System.out.println('运行时间:' + ((System.currentTimeMillis() - sT) /1000) + 's');}执行结果:

[ { '$match' : { 'usedDayFlow' : 2}} , { '$group' : { '_id' : null , 'count' : { '$sum' : 1}}}]

[{ '_id' : null , 'count' : 1002223}]

该统计结果比实际数据量要多一些,请教大神,对于分片集群的聚合统计要如何操作?

问题解答

回答1: 该问题已经解决,使用的是最新驱动mongo-java-driver-3.4.0,通过下面的方法可以在分片集群模式下,准确的统计到记录数量,感谢大家的相助!mongo shell >> db.collection.aggregate([{$match:{categories:'Bakery'},{$group:{'_id':null,'count':{$sum:1}}}}])

public long getCount() {String user = '用户名';String database = 'admin';String password = '密码';MongoCredential credential = MongoCredential.createCredential(user,database, password.toCharArray());MongoClientOptions options = MongoClientOptions.builder().connectionsPerHost(10).threadsAllowedToBlockForConnectionMultiplier(10).socketTimeout(20000).connectTimeout(15000).maxWaitTime(50000).build();MongoClient mongoClient = new MongoClient(new ServerAddress('IP地址', '端口'), Arrays.asList(credential), options);MongoDatabase mongoDatabase = mongoClient.getDatabase('数据库');MongoCollection<Document> collection = mongoDatabase.getCollection('数据表');final long[] count = new long[1];Block<Document> printBlock = new Block<Document>() { @Override public void apply(final Document document) { count[0] = (long) document.get('count'); }};Bson bson = Filters.eq('categories', 'Bakery');collection.aggregate(Arrays.asList(Aggregates.match(bson),Aggregates.group(null, Accumulators.sum('count', 1L)))).forEach(printBlock);return count[0];}回答2:

能否补充一些评论中的信息。多谢!

将评论的内容转发在这里,方便查看:

1、count和aggregate的不同:在mongoDB中,count和aggregate是在两支不同的程序中实现的,aggregate的实现是考虑到了shard的环境的,所以官方文档是推荐使用aggregate来进行shard环境下的count。

2、MongoDB shell下使用aggregate和使用Java MongoDB驱动使用aggregate来进行count,结果应该是一样的,因为两者都是使用的aggregate。

您提到Issue大概是MongoDB shell和Java MongoDB驱动进行count的结果不一致。

这种不一致,我觉得可能是:

1)比较的过程有没有纰漏;2)所用的Java MongoDB驱动是否有纰漏。

供参考。

Love MongoDB! Have Fun!

今晚8点,MongoDB中文社区大神在线讲座,请大家踊跃参与;此大神常驻本版哦!

请戳此链接。

标签: java