【问题标题】:MongoDB distinct too big 16mb capMongoDB 明显太大 16mb 上限
【发布时间】:2014-12-05 19:16:35
【问题描述】:

我有一个 Mongodb 集合。简单地说,它有两列:用户和网址。它有 39274590 行。该表的键是 {user, url}。

使用 Java,我尝试列出不同的 url:

  MongoDBManager db = new MongoDBManager( "Website", "UserLog" );
  return db.getDistinct("url"); 

但我收到一个异常:

Exception in thread "main" com.mongodb.CommandResult$CommandFailure: command failed [distinct]: 
{ "serverUsed" : "localhost/127.0.0.1:27017" , "errmsg" : "exception: distinct too big, 16mb cap" , "code" : 10044 , "ok" : 0.0}

我该如何解决这个问题?有没有plan B可以避免这个问题?

【问题讨论】:

  • 你找到解决方案了吗?

标签: java mongodb


【解决方案1】:

在 2.6 版中,您可以使用聚合命令来生成单独的集合: http://docs.mongodb.org/manual/reference/operator/aggregation/out/

对于大多数查询,这将绕过 mongodb 的 16mb 限制。您可以在此处阅读有关在 mongodb 2.6 中的大型数据集上使用聚合框架的更多信息: http://vladmihalcea.com/mongodb-2-6-is-out/

要使用聚合框架进行“不同”查询,请按字段分组。

db.userlog.aggregate([{$group: {_id: '$url'} }]); 

注意:我不知道这对 Java 驱动程序是如何工作的,祝你好运。

【讨论】:

  • 它给了我用户 ID 的列表,我怎样才能得到那个计数
【解决方案2】:

看看这个answer

1) 最简单的方法是通过聚合框架。这需要两个“$group”命令:第一个按不同的值分组,第二个计算所有不同的值

2) 如果您想使用 Map/Reduce 执行此操作,您可以。这也是一个两阶段的过程:在第一阶段,我们构建一个新集合,其中包含键的每个不同值的列表。在第二个中,我们对新集合执行 count()。

请注意,您不能返回内联 map/reduce 的结果,因为这可能会超出 16MB 的文档大小限制。可以将计算保存在一个集合中,然后count()计算集合的大小,也可以从mapReduce()的返回值中获取结果个数。

【讨论】:

    【解决方案3】:

    如果您使用的是 mongodb 3.0 及更高版本,则可以使用 具有 batchSize 的 DistinctIterable 类。

    MongoCollection coll = null;
    coll = mongodb.getCollection("mycollection");
    DistinctIterable<String> ids = coll.distinct("id", String.class).batchSize(100);
    for (String id: ids) {
        System.out.println("" + id);
    }
    

    http://api.mongodb.com/java/current/com/mongodb/client/DistinctIterable.html

    【讨论】:

      【解决方案4】:

      Groovy 上的 3.x 版:

      import com.mongodb.client.AggregateIterable
      import com.mongodb.client.MongoCollection
      import com.mongodb.client.MongoCursor
      import com.mongodb.client.MongoDatabase
      import static com.mongodb.client.model.Accumulators.sum
      import static com.mongodb.client.model.Aggregates.group
      import static java.util.Arrays.asList
      import org.bson.Document
      
      //other code
      
      AggregateIterable<Document> iterable = collection.aggregate(
          asList(
              group("\$" + "url", sum("count", 1))
          )
      ).allowDiskUse(true)
      
      MongoCursor cursor = iterable.iterator()
      
      while(cursor.hasNext()) {
          Document doc = cursor.next()
          println(doc.toJson())
      }
      

      【讨论】:

        猜你喜欢
        • 2018-09-21
        • 2018-09-11
        • 2013-02-24
        • 1970-01-01
        • 2017-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多