汇总匹配 true 的字段数
Aggregating number of fields that match true
我正在努力处理 mongodb 中的聚合。我有以下类型的文件:
{
"_id": "xxxx",
"workHome": true,
"commute": true,
"tel": false,
"weekend": true,
"age":39
},
{
"_id": "yyyy",
"workHome": false,
"commute": true,
"tel": false,
"weekend": true,
"age":32
},
{
"_id": "zzzz",
"workHome": false,
"commute": false,
"tel": false,
"weekend": false,
"age":27
}
除此之外,我想根据文档中 "true" 的字段总数生成一个聚合。文档中共有 4 个布尔字段,因此我希望查询将它们组合在一起以生成以下输出(例如来自总共包含 100 个文档的集合的示例):
0:20
1:30
2:10
3:20
4:20
这意味着:100 个文档中有 20 个 'all false',30 个文档“1x true”,10 个文档“2x true”等,总共 'all 4 are true'。
有什么方法可以用 $aggregate 语句做到这一点吗?现在我正在尝试按 'true' 值的 $sum 进行 $group,但没有找到使条件查询起作用的方法。
因此假设数据与 "workHome"、"commute"、"tel" 和 "weekend" 的所有相同字段一致,那么您将继续 "logical"这样的评价:
db.collection.aggregate([
{ "$project": {
"mapped": { "$map": {
"input": ["A","B","C","D"],
"as": "el",
"in": { "$cond": [
{ "$eq": [ "$$el", "A" ] },
"$workHome",
{ "$cond": [
{ "$eq": [ "$$el", "B" ] },
"$commute",
{ "$cond": [
{ "$eq": [ "$$el", "C" ] },
"$tel",
"$weekend"
]}
]}
]}
}}
}},
{ "$unwind": "$mapped" },
{ "$group": {
"_id": "$_id",
"size": { "$sum": { "$cond": [ "$mapped", 1, 0 ] } }
}},
{ "$group": {
"_id": "$size",
"count": { "$sum": 1 }
}},
{ "$sort": { "_id": 1 } }
])
从您的简单示例中得出:
{ "_id" : 0, "count" : 1 }
{ "_id" : 2, "count" : 1 }
{ "_id" : 3, "count" : 1 }
要分解它,首先是 $map
operator here transposes the values of the fields to an array of the same lenght as the fields themselves. This is done my comparing each element of the "input" to an expected value via $cond
and either returning the true
condtion where a match, or moving on to the next condition embedded in the false
part of this "ternary" 运算符。这样做直到满足所有逻辑匹配并从字段中产生一个值数组,对于第一个文档:
[true,true,false,true]
下一步是对$unwind
数组元素作进一步比较。这 "de-normalizes" 为每个数组元素分成单独的文档,并且在处理数组时通常在聚合管道中需要。
完成后,一个 $group
pipeline stage is invoked, in order to assess the "total" of those elements with a true
value. The same $cond
ternary is used to transform the logical true/false
condtions into numeric values here and fed to the $sum
累加器用于加法。
由于 $group
中 _id
中提供的 "grouping key" 是原始文档 _id
值,因此当前总计是每个文档的那些字段的 true
。为了获得整个集合(或选择)的 "counts" 的总计,然后调用进一步的 $group
阶段,分组键是匹配的 [=16= 返回的 "size" ] 每个文档的结果。
那里使用的 $sum
累加器简单地为分组键上的每个匹配添加 1
,因此 "counting" 每个匹配计数的出现次数。
最后 $sort
通过匹配的数量 "key" 来产生一些结果的顺序。
郑重声明,即将发布的 MongoDB(截至撰写本文时)它包含了 $filter
运算符:
db.collection.aggregate([
{ "$group": {
"_id": {
"$size": {
"$filter": {
"input": { "$map": {
"input": ["A","B","C","D"],
"as": "el",
"in": { "$cond": [
{ "$eq": [ "$$el", "A" ] },
"$workHome",
{ "$cond": [
{ "$eq": [ "$$el", "B" ] },
"$commute",
{ "$cond": [
{ "$eq": [ "$$el", "C" ] },
"$tel",
"$weekend"
]}
]}
]}
}},
"as": "el",
"cond": {
"$eq": [ "$$el", true ]
}
}
}
},
"count": { "$sum": 1 }
}},
{ "$sort": { "_id": 1 } }
])
所以现在 "two" 流水线阶段做的事情与将在 MongoDB 2.6 及更高版本中运行的原始语句相同。
因此,如果您自己的应用程序在 "development" 本身,或者您有其他好奇,请查看 Development Branch releases 现在可以使用此功能的地方。
我正在努力处理 mongodb 中的聚合。我有以下类型的文件:
{
"_id": "xxxx",
"workHome": true,
"commute": true,
"tel": false,
"weekend": true,
"age":39
},
{
"_id": "yyyy",
"workHome": false,
"commute": true,
"tel": false,
"weekend": true,
"age":32
},
{
"_id": "zzzz",
"workHome": false,
"commute": false,
"tel": false,
"weekend": false,
"age":27
}
除此之外,我想根据文档中 "true" 的字段总数生成一个聚合。文档中共有 4 个布尔字段,因此我希望查询将它们组合在一起以生成以下输出(例如来自总共包含 100 个文档的集合的示例):
0:20
1:30
2:10
3:20
4:20
这意味着:100 个文档中有 20 个 'all false',30 个文档“1x true”,10 个文档“2x true”等,总共 'all 4 are true'。
有什么方法可以用 $aggregate 语句做到这一点吗?现在我正在尝试按 'true' 值的 $sum 进行 $group,但没有找到使条件查询起作用的方法。
因此假设数据与 "workHome"、"commute"、"tel" 和 "weekend" 的所有相同字段一致,那么您将继续 "logical"这样的评价:
db.collection.aggregate([
{ "$project": {
"mapped": { "$map": {
"input": ["A","B","C","D"],
"as": "el",
"in": { "$cond": [
{ "$eq": [ "$$el", "A" ] },
"$workHome",
{ "$cond": [
{ "$eq": [ "$$el", "B" ] },
"$commute",
{ "$cond": [
{ "$eq": [ "$$el", "C" ] },
"$tel",
"$weekend"
]}
]}
]}
}}
}},
{ "$unwind": "$mapped" },
{ "$group": {
"_id": "$_id",
"size": { "$sum": { "$cond": [ "$mapped", 1, 0 ] } }
}},
{ "$group": {
"_id": "$size",
"count": { "$sum": 1 }
}},
{ "$sort": { "_id": 1 } }
])
从您的简单示例中得出:
{ "_id" : 0, "count" : 1 }
{ "_id" : 2, "count" : 1 }
{ "_id" : 3, "count" : 1 }
要分解它,首先是 $map
operator here transposes the values of the fields to an array of the same lenght as the fields themselves. This is done my comparing each element of the "input" to an expected value via $cond
and either returning the true
condtion where a match, or moving on to the next condition embedded in the false
part of this "ternary" 运算符。这样做直到满足所有逻辑匹配并从字段中产生一个值数组,对于第一个文档:
[true,true,false,true]
下一步是对$unwind
数组元素作进一步比较。这 "de-normalizes" 为每个数组元素分成单独的文档,并且在处理数组时通常在聚合管道中需要。
完成后,一个 $group
pipeline stage is invoked, in order to assess the "total" of those elements with a true
value. The same $cond
ternary is used to transform the logical true/false
condtions into numeric values here and fed to the $sum
累加器用于加法。
由于 $group
中 _id
中提供的 "grouping key" 是原始文档 _id
值,因此当前总计是每个文档的那些字段的 true
。为了获得整个集合(或选择)的 "counts" 的总计,然后调用进一步的 $group
阶段,分组键是匹配的 [=16= 返回的 "size" ] 每个文档的结果。
那里使用的 $sum
累加器简单地为分组键上的每个匹配添加 1
,因此 "counting" 每个匹配计数的出现次数。
最后 $sort
通过匹配的数量 "key" 来产生一些结果的顺序。
郑重声明,即将发布的 MongoDB(截至撰写本文时)它包含了 $filter
运算符:
db.collection.aggregate([
{ "$group": {
"_id": {
"$size": {
"$filter": {
"input": { "$map": {
"input": ["A","B","C","D"],
"as": "el",
"in": { "$cond": [
{ "$eq": [ "$$el", "A" ] },
"$workHome",
{ "$cond": [
{ "$eq": [ "$$el", "B" ] },
"$commute",
{ "$cond": [
{ "$eq": [ "$$el", "C" ] },
"$tel",
"$weekend"
]}
]}
]}
}},
"as": "el",
"cond": {
"$eq": [ "$$el", true ]
}
}
}
},
"count": { "$sum": 1 }
}},
{ "$sort": { "_id": 1 } }
])
所以现在 "two" 流水线阶段做的事情与将在 MongoDB 2.6 及更高版本中运行的原始语句相同。
因此,如果您自己的应用程序在 "development" 本身,或者您有其他好奇,请查看 Development Branch releases 现在可以使用此功能的地方。