MongoDB:如何计算文档中的键数?

时间:2012-01-23 23:31:53

标签: mongodb

让我们说文件是:

{

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

如何计算此类文件中的密钥数量?

谢谢

7 个答案:

答案 0 :(得分:9)

没有内置命令。获取此文档并自行计算密钥。

答案 1 :(得分:7)

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

答案 2 :(得分:5)

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

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

在获取数组时,您可以利用$addFields管道步骤创建一个包含计数的字段,并使用 $size <派生实际计数/ strong>运营商。

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

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" ] }
                    }
                }
            }
        }
    }     
])

答案 3 :(得分:2)

如果你在Mongo控制台,你可以编写javascript来做到这一点。

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

这仍将被视为&#34;在mongo&#34;之外虽然。

答案 4 :(得分:1)

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

您可以这样做:

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

答案 5 :(得分:1)

如果您正在使用 mongoose.Document 之类的 Documents ,则可以尝试在转换为对象,因为 doc 之前只有commom属性:

Error:(42, 12) Cannot find or construct a Read instance for type:
  T
This can happen for a few reasons, but the most common case is that a data
member somewhere within this type doesn't have a Get instance in scope. Here are
some debugging hints:
- For Option types, ensure that a Read instance is in scope for the non-Option
  version.
- For types you expect to map to a single column ensure that a Get instance is
  in scope.
- For case classes, HLists, and shapeless records ensure that each element
  has a Read instance in scope.
- Lather, rinse, repeat, recursively until you find the problematic bit.
You can check that an instance exists for Read in the REPL or in your code:
  scala> Read[Foo]
and similarly with Get:
  scala> Get[Foo]
And find the missing instance and construct it as needed. Refer to Chapter 12
of the book of doobie for more information.
    f.query[T].option.transact(xa).unsafeRunSync()

Error:(42, 12) not enough arguments for method query: (implicit evidence$1: doobie.util.Read[T], implicit h: doobie.LogHandler)doobie.Query0[T].
Unspecified value parameter evidence$1.
    f.query[T].option.transact(xa).unsafeRunSync()

因此,尝试将对象传递给 Object.keys

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

并显示键计数

console.dir(
    Object.keys(document.toObject()) // Returns ['prop1', 'prop2', 'prop3']
);

并且要开心!

答案 6 :(得分:0)

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();
})();