7

我有一组像这样的文件:

{
    "_id" : ObjectId("..."),
    "field1": "some string",
    "field2": "another string",
    "field3": 123
}

我希望能够遍历整个集合,并找到所有字段数。在这个示例文档中,有 3 个(我不想包含 _id),但它的范围是文档中的 2 到 50 个字段。最终,我只是在寻找每个文档的平均字段数。

有任何想法吗?

4

4 回答 4

8

遍历整个集合,并找到所有字段数

现在您可以利用聚合运算符$objectToArray ( SERVER-23310 ) 将键转换为值并对其进行计数。此运算符在 MongoDB v3.4.4+ 中可用

例如:

db.collection.aggregate([
         {"$project":{"numFields":{"$size":{"$objectToArray":"$$ROOT"}}}}, 
         {"$group":{"_id":null, "fields":{"$sum":"$numFields"}, "docs":{"$sum":1}}}, 
         {"$project":{"total":{"$subtract":["$fields", "$docs"]}, _id:0}}
])

第一阶段$project是将所有键转换为数组以计数字段。第二阶段$group是汇总集合中键/字段的数量,以及处理的文档数量。第三阶段$project是用文档总数减去字段总数(因为您不想计算_id)。

您可以轻松添加$avg以计算最后阶段的平均值。

于 2017-05-12T05:57:37.757 回答
4
PRIMARY> var count = 0;
PRIMARY> db.my_table.find().forEach( function(d) { for(f in d) { count++; } });
PRIMARY> count
1074942

这是我能弄清楚如何做到这一点的最简单的方法。在非常大的数据集上,走 Map-Reduce 路径可能是有意义的。但是,虽然你的集合足够小,但也可以。

这是O(n^2),但我不确定是否有更好的方法。

于 2012-12-11T00:34:39.290 回答
2

您可以创建一个 Map-Reduce 作业。在 Map 步骤中,将每个文档的属性作为 javascript 对象进行迭代,输出计数并减少以获取总数。

于 2012-12-11T00:03:07.177 回答
0

对于一种简单的方法,只需 find() 所有值并为每组记录获取数组的大小。

db.getCollection().find(<condition>)

然后对于每组结果,获取数组的大小。

sizeOf(Array[i])
于 2015-12-14T09:40:31.953 回答