Arrays MongoDB获取数组中特定键的计数
在mongoDB中,如何获得数组中特定键的计数Arrays MongoDB获取数组中特定键的计数,arrays,mongodb,mongo-shell,Arrays,Mongodb,Mongo Shell,在mongoDB中,如何获得数组中特定键的计数 { "_id" : ObjectId("52d9212608a224e99676d378"), "business" : [ { "name" : "abc", "rating" : 4.5 }, { "name" : "pqr" }, { "name" : "xyz", "rating" : 3.6 } ] } 在上面的示例中,业务是一个数组(带有“name”和/或“rating”键)
{
"_id" : ObjectId("52d9212608a224e99676d378"),
"business" : [
{
"name" : "abc",
"rating" : 4.5
},
{
"name" : "pqr"
},
{
"name" : "xyz",
"rating" : 3.6
}
]
}
在上面的示例中,业务是一个数组(带有“name”和/或“rating”键)
如何获得仅存在“评级”键的业务阵列计数
预期输出为:2看起来您必须使用。特别是,您需要修改数组,然后只匹配包含
评级
字段的元素,然后将文档恢复为原始格式
试着这样做:
db.test.aggregate([
{ $match: { /* your query criteria document */ } },
{ $unwind: "$business" },
{ $match: {
"business.rating": { $exists: 1 }
}
},
{ $group: {
_id: "$_id",
business: { $push: "$business" },
business_count: { $sum: 1 }
}
}
])
结果如下所示:
{
_id: ObjectId("52d9212608a224e99676d378"),
business: [
{ name: "abc", rating: 4.5 },
{ name: "xyz", rating: 3.6 }
],
business_count: 2
}
UPD看起来OP不想通过包装文档
\u id
字段对结果进行分组。不幸的是,$group
表达式必须指定\u id
值,否则会异常失败。但是,该值实际上可以是常量(例如,纯null
或'foobar'
),因此只有一个结果组具有集合方式聚合。看起来您必须使用。特别是,您需要修改数组,然后只匹配包含评级
字段的元素,然后将文档恢复为原始格式
试着这样做:
db.test.aggregate([
{ $match: { /* your query criteria document */ } },
{ $unwind: "$business" },
{ $match: {
"business.rating": { $exists: 1 }
}
},
{ $group: {
_id: "$_id",
business: { $push: "$business" },
business_count: { $sum: 1 }
}
}
])
结果如下所示:
{
_id: ObjectId("52d9212608a224e99676d378"),
business: [
{ name: "abc", rating: 4.5 },
{ name: "xyz", rating: 3.6 }
],
business_count: 2
}
UPD看起来OP不想通过包装文档
\u id
字段对结果进行分组。不幸的是,$group
表达式必须指定\u id
值,否则会异常失败。但是,该值实际上可以是常量(例如,纯null
或'foobar'
),因此只有一个具有集合聚合的结果组。我喜欢您的代码示例(它可以工作,所以+1)。将来,请使用test
数据库(而不是foo
),这样我们就可以在mongo shell中保存键入和编辑了。。。。因此,评论;)@ixe013正常;)顺便说一句,foo在这里不是一个数据库名称-它是一个集合名称。而collectiontest
没有任何特殊意义(与mongoshell中默认的数据库test
不同)。是的,collection。当我阅读问题时,我在默认的test
集合中创建了OP文档。没什么大不了的,我想我只是在短暂的一夜之后,今天早上脾气暴躁罢了!我喜欢这个解决方案。但是为了过滤掉在业务数组的任何元素中都没有评级键的文档,我将在$unwind pipe之前添加“{$match:{$business:{$elemMatch:{$rating:{$exists:true}}}}”。请参阅@user3195726伟大的建议!这是一种优化,我只是在这里展示一般的技术。我喜欢你的代码示例(它可以工作,所以+1)。将来,请使用test
数据库(而不是foo
),这样我们就可以在mongo shell中保存键入和编辑了。。。。因此,评论;)@ixe013正常;)顺便说一句,foo在这里不是一个数据库名称-它是一个集合名称。而collectiontest
没有任何特殊意义(与mongoshell中默认的数据库test
不同)。是的,collection。当我阅读问题时,我在默认的test
集合中创建了OP文档。没什么大不了的,我想我只是在短暂的一夜之后,今天早上脾气暴躁罢了!我喜欢这个解决方案。但是为了过滤掉在业务数组的任何元素中都没有评级键的文档,我将在$unwind pipe之前添加“{$match:{$business:{$elemMatch:{$rating:{$exists:true}}}}”。请参阅@user3195726伟大的建议!这是一种优化,我只是在这里展示一般的技术。因此,让我们将此作为评论。