【问题标题】:Construct count query in MongoDB在 MongoDB 中构造计数查询
【发布时间】:2017-07-08 15:21:27
【问题描述】:

我有一个 MongoDB 数据库,其中包含如下所示的文档:

{"users" : ["u1", "u2", "u3"]}
{"users" : ["u1", "u4"]}
{"users" : ["u1", "u3", "u5", "u6", "u7"]}

我想获取用户数较多的文档的计数。使用上述内容,查询将返回 5 作为数据库中的最高用户数。我怎样才能在 MongoDB 中做到这一点?

我可以通过以下方式获取特定大小的文档数量:

db.mydb.find({users: {$size: 5}}).count()

但是,我不知道如何在用户数组中的所有文档中找到最大计数。

谢谢。

【问题讨论】:

    标签: mongodb nosql


    【解决方案1】:

    您不能直接在 MongoDB 中执行此操作。但是,您可以在同一个文档中添加一个名为“user_count”和use the $inc operator 的额外字段,以便在每次将新用户添加到“users”数组时将其加一。

    您的更新将类似于:

    db.mydb.update({<update_condition>}, {$push :{"users":"u8"}, $inc : {"user_count":1}})
    

    【讨论】:

      【解决方案2】:

      以下是 MongoDB 中的三个有效解决方案,但 Asya 的回答可能更合适,具体取决于您的工程需求。您应该回答以下问题:我的收藏有多大,每种潜在解决方案的成本/效率是多少?还有其他性能问题吗?我可以通过在问题域中记账来更有效地解决这个问题吗?

      如果这是一个常见问题,您应该考虑通过您的应用程序显式跟踪最大计数。为了增加用户,您只需跟踪最大值。但是(仅)如果文档从当前最大值减少,您必须支付完整查询的费用。 Asya 的解决方案可能仍然有助于完成这个完整的查询。

      这里是 MongoDB 的可能性。请仔细检查有关您的问题和性能或工程影响的文档。

      1. db.eval 服务器大小的代码执行 - http://www.mongodb.org/display/DOCS/Server-side+Code+Execution

        注意:对于长时间运行的作业,请使用 map/reduce 而不是 db.eval()。 db.eval 阻止其他操作!

      2. 聚合“组” - http://www.mongodb.org/display/DOCS/Aggregation

      3. MapReduce - http://www.mongodb.org/display/DOCS/MapReduce

      count_query.js

      db.mydb.drop();
      db.mydb.save({"users" : ["u1", "u2", "u3"]});
      db.mydb.save({"users" : ["u1", "u4"]});
      db.mydb.save({"users" : ["u1", "u3", "u5", "u6", "u7"]});
      //printjson(db.mydb.find().toArray());
      
      printjson(db.eval(function() {
          var count = 0;
          db.mydb.find().forEach( function(doc) {
              if (doc.users.length > count)
                  count = doc.users.length;
          });
          return count;
      }));
      
      printjson(db.mydb.group({
          reduce: function(doc, prev) {
              if (doc.users.length > prev.count)
                  prev.count = doc.users.length;
          },
          initial: {count: 0}
      })[0].count);
      
      printjson(db.mydb.mapReduce(
          function() { emit(0, {count: this.users.length}); },
          function(key, values) {
              var result = {count: 0};
              values.forEach(function(value) {
                  if (value.count > result.count)
                      result.count = value.count;
              });
              return result;
          },
          {out: {inline: 1}}  
      ).results[0].value.count);
      

      执行与输出

      $ mongo count_query.js
      MongoDB shell version: 2.0.4
      connecting to: test
      5
      5
      5
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-13
        • 2021-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多