MongoDB 基于一个字段的输出计数
MongoDB Count based on output on one field
假设我有以下数据集,
//listings collection
{
"city": New York,
"beds": 2,
"build": concrete
}
{
"city": New York,
"beds": 4,
"build": wood
}
{
"city": New York,
"beds": 3,
"build": asphalt
}
{
"city": New York,
"beds": 1,
"build": concrete
}
我可以通过以下查询获得以下平均床位数量
db.listings.aggregate(
[
{
$match: {
"city": "New York"
}
},
{
$group: {
"_id": null,
"Avg-Beds": {
$avg:"$beds
}
}
}
])
这很酷,但我真正想要的是
{
"Avg-Beds": 2
"Build" {
"Asphalt" : 1,
"Wood": 1,
"Concrete": 2
}
综上所述,我想平均床位,但我想同时统计"build"
字段的输出。
mongodb 是如何实现的?
更好的是像
的输出
"Build": {
"Asphalt": "25%"
}
这将给出基于百分比的值。请注意,我没有一组预定义的 "build"
输出字段。
您可以尝试以下聚合:
db.listings.aggregate([
{
$match: { "city": "New York" }
},
{
$group: {
_id: null,
avg: { $avg: "$beds" },
docs: { $push: "$$ROOT" }
}
},
{
$unwind: "$docs"
},
{
$group: {
_id: "$docs.build",
avg: { $first: "$avg" },
beds: { $sum: "$docs.beds" }
}
},
{
$group: {
_id: null,
avg: { $first: "$avg" },
total: { $sum: "$beds" },
Build: { $push: { k: "$_id", v: "$beds" } }
}
},
{
$addFields: {
Build: {
$map: {
input: "$Build",
as: "b",
in: {
k: "$$b.k",
v: { $divide: [ "$$b.v", "$total" ] }
}
}
}
}
},
{
$project: {
_id: 0,
avg: 1,
Build: { $arrayToObject: "$Build" }
}
}
])
问题是你需要多个独立的聚合,所以你可以执行第一个 ($avg
),然后将其结果嵌入到你集合的每个文档中(将所有文档推送到 docs
字段下以及展开那个领域)。然后你可以构建一个 k
-v
对的数组来应用 $arrayToObject 来表示百分比。
结果你会得到:
{ "avg" : 2.5, "Build" : { "asphalt" : 0.3, "wood" : 0.4, "concrete" : 0.3 } }
假设我有以下数据集,
//listings collection
{
"city": New York,
"beds": 2,
"build": concrete
}
{
"city": New York,
"beds": 4,
"build": wood
}
{
"city": New York,
"beds": 3,
"build": asphalt
}
{
"city": New York,
"beds": 1,
"build": concrete
}
我可以通过以下查询获得以下平均床位数量
db.listings.aggregate(
[
{
$match: {
"city": "New York"
}
},
{
$group: {
"_id": null,
"Avg-Beds": {
$avg:"$beds
}
}
}
])
这很酷,但我真正想要的是
{
"Avg-Beds": 2
"Build" {
"Asphalt" : 1,
"Wood": 1,
"Concrete": 2
}
综上所述,我想平均床位,但我想同时统计"build"
字段的输出。
mongodb 是如何实现的?
更好的是像
的输出"Build": {
"Asphalt": "25%"
}
这将给出基于百分比的值。请注意,我没有一组预定义的 "build"
输出字段。
您可以尝试以下聚合:
db.listings.aggregate([
{
$match: { "city": "New York" }
},
{
$group: {
_id: null,
avg: { $avg: "$beds" },
docs: { $push: "$$ROOT" }
}
},
{
$unwind: "$docs"
},
{
$group: {
_id: "$docs.build",
avg: { $first: "$avg" },
beds: { $sum: "$docs.beds" }
}
},
{
$group: {
_id: null,
avg: { $first: "$avg" },
total: { $sum: "$beds" },
Build: { $push: { k: "$_id", v: "$beds" } }
}
},
{
$addFields: {
Build: {
$map: {
input: "$Build",
as: "b",
in: {
k: "$$b.k",
v: { $divide: [ "$$b.v", "$total" ] }
}
}
}
}
},
{
$project: {
_id: 0,
avg: 1,
Build: { $arrayToObject: "$Build" }
}
}
])
问题是你需要多个独立的聚合,所以你可以执行第一个 ($avg
),然后将其结果嵌入到你集合的每个文档中(将所有文档推送到 docs
字段下以及展开那个领域)。然后你可以构建一个 k
-v
对的数组来应用 $arrayToObject 来表示百分比。
结果你会得到:
{ "avg" : 2.5, "Build" : { "asphalt" : 0.3, "wood" : 0.4, "concrete" : 0.3 } }