【问题标题】:MongoDB: how to count number of keys in a document?MongoDB:如何计算文档中的键数?
【发布时间】:2012-02-17 07:19:07
【问题描述】:

假设一个文档是:

{

a: 1,
b: 1,
c: 2,
 ....
z: 2
}

如何计算此类文档中的键数?

谢谢

【问题讨论】:

  • 为什么会遭到反对?这是一个相当合理的问题。点赞。

标签: mongodb


【解决方案1】:

没有用于此的内置命令。获取此文档并自己计算密钥。

【讨论】:

    【解决方案2】:

    Sergio 是对的,你必须在 mongo 之外进行。

    你可以这样做:

    var count = 0;
    for(k in obj) {count++;}
    print(count);
    

    【讨论】:

      【解决方案3】:

      在 Mongo 中(就像在大多数 NoSQL 解决方案中一样),如果您想稍后对这些值进行查询(例如“不同键的数量 > 12”),那么预先计算这些值通常是一个好主意,所以也许您应该考虑添加一个新字段“keyCount”,每次添加新键时都会递增。

      【讨论】:

        【解决方案4】:

        如果您在 Mongo 控制台中,您可以编写 javascript 来执行此操作。

        doc = db.coll.findOne({}); nKeys =0; for( k in doc){nKeys ++;} print(nKeys);
        

        不过,这仍将被视为“在 mongo 之外”。

        【讨论】:

        • 你也可以nKeys = Object.keys(doc).length;
        【解决方案5】:

        如果通过聚合框架使用 MongoDB 3.6 和更新版本,则很有可能。 在聚合管道中使用 $objectToArray 运算符将文档转换为数组。返回数组包含原始文档中每个字段/值对的元素。返回数组中的每个元素都是一个包含两个字段kv 的文档。

        通过 $$ROOT 系统变量可以引用文档的根目录,该系统变量引用当前在聚合管道阶段处理的顶级文档。

        在获取数组后,您可以利用 $addFields 管道步骤创建一个保存计数的字段,并使用 $size 运算符得出实际计数.

        所有这些都可以通过嵌套表达式在单个管道中完成,如下所示:

        db.collection.aggregate([
            { "$addFields": {
                "count": {
                    "$size": { 
                        "$objectToArray": "$$ROOT"
                    }
                }
            } }     
        ])
        

        示例输出

        {
            "_id" : ObjectId("5a7cd94520a31e44e0e7e282"),
            "a" : 1.0,
            "b" : 1.0,
            "c" : 2.0,
            "z" : 2.0,
            "count" : 5
        }
        

        要排除 _id 字段,您可以使用 $filter 运算符:

        db.collection.aggregate([
            {
                "$addFields": {
                    "count": {
                        "$size": { 
                            "$filter": {
                                "input": { "$objectToArray": "$$ROOT" },
                                "as": "el",
                                "cond": { "$ne": [ "$$el.k", "_id" ] }
                            }
                        }
                    }
                }
            }     
        ])
        

        或者按照0zkr PM 的建议,只需在开头添加一个$project 管道步骤:

        db.collection.aggregate([
            { "$project": { "_id": 0 } },
            { "$addFields": {
                "count": {
                    "$size": { 
                        "$objectToArray": "$$ROOT"
                    }
                }
            } }     
        ])
        

        【讨论】:

        • 在聚合管道中添加一个$project 来代替filter
        【解决方案6】:
        const MongoClient = new require("mongodb").MongoClient(
          "mongodb://localhost:27017",
          {
            useNewUrlParser: true,
            useUnifiedTopology: true
          }
        );
        (async () => {
          const connection = await MongoClient.connect();
          const dbStuff = await connection
            .db("db")
            .collection("weedmaps.com/brands")
            .find({})
            .toArray();  // <- Chuck all it into an Array
          for (let thing of dbStuff) {
            console.log(Object.keys(thing).length);
          }
          return await connection.close();
        })();
        

        【讨论】:

          【解决方案7】:

          如果您正在使用 Documents,例如 mongoose.Document,您可以尝试在转换后计算 doc 中的所有键对象,因为在它之前,doc 只是有通用属性:

          Object.keys(document); // returns [ '$__', 'isNew', 'errors', '_doc', '$locals' ]
          Object.keys(document).length; // returns ALWAYS 5
          

          所以,在将它传递给 Object.keys

          之后,尝试强制转换为一个对象
          console.dir(
              Object.keys(document.toObject()) // Returns ['prop1', 'prop2', 'prop3']
          );
          

          并显示键数

          console.log(
              Object.keys(document.toObject().length)
          ); // Returns 3
          

          要快乐!!!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多