MongoDB:聚合较低级别的数据
MongoDB: aggregating data in lower levels
我有一个名为 trips
的 mongoDB 数据库,其结构如下:
{'Name': 'Joe Doe',
'WentTo' :
[{ 'Destination':
{ 'City': 'Tirana',
'Country': 'Albania'}},
{ 'Destination':
{ 'City': 'Bari',
'Country': 'Italy'}},
{ 'Destination':
{ 'City': 'Pisa',
'Country': 'Italy'}} }] }
{'Name': 'Jane Doe',
'WentTo' :
[{ 'Destination':
{ 'City': 'Perth',
'Country': 'Australia'}},
{ 'Destination':
{ 'City': 'Bern',
'Country': 'Switzerland'}},
{ 'Destination':
{ 'City': 'Rome',
'Country': 'Italy'}} }] }
我想列出去过意大利的旅行者和他们去过那里的次数,像这样:
{ "Name" : "Joe Doe", "Times in Italy" : 2 }
{ "Name" : "Jane Doe", "Times in Italy" : 1 }
我想到了这个方法,但是 MongoDB 没有输出任何东西。
db.trips.aggregate([ {$unwind:'$WentTo.Destination'},
{$match: {'Country':'Italy'}}, {$group:{_id:'$Name', Times in Italy:{$sum:1}}}])
有什么想法吗?
可能是这样的:
选项 1:
$filter/$size(当没有同名的重复记录时更快更有效)
db.collection.aggregate([
{
"$addFields": {
"WentTo": {
$size: {
"$filter": {
"input": "$WentTo",
"as": "w",
"cond": {
"$eq": [
"$$w.Destination.Country",
"Italy"
]
}
}
}
}
}
},
{
$project: {
"Times in Italy": "$WentTo",
Name:1
}
}
])
解释:
- 将 addFields 与 $filter 结合使用以仅匹配以意大利为国家/地区的数组元素并使用 $size
对它们进行计数
- 将“WentTo”数组投影为“Times in Italy”并按要求命名。
选项 2:
这是对您的查询进行了小的更正,也涵盖了每个名称存在重复记录的情况,请注意更大的集合 $unwind 操作可能会影响性能并且速度慢...
db.collection.aggregate([
{
$unwind: "$WentTo"
},
{
$match: {
"WentTo.Destination.Country": "Italy"
}
},
{
$group: {
_id: "$Name",
"Times in Italy": {
$sum: 1
}
}
}
])
我有一个名为 trips
的 mongoDB 数据库,其结构如下:
{'Name': 'Joe Doe',
'WentTo' :
[{ 'Destination':
{ 'City': 'Tirana',
'Country': 'Albania'}},
{ 'Destination':
{ 'City': 'Bari',
'Country': 'Italy'}},
{ 'Destination':
{ 'City': 'Pisa',
'Country': 'Italy'}} }] }
{'Name': 'Jane Doe',
'WentTo' :
[{ 'Destination':
{ 'City': 'Perth',
'Country': 'Australia'}},
{ 'Destination':
{ 'City': 'Bern',
'Country': 'Switzerland'}},
{ 'Destination':
{ 'City': 'Rome',
'Country': 'Italy'}} }] }
我想列出去过意大利的旅行者和他们去过那里的次数,像这样:
{ "Name" : "Joe Doe", "Times in Italy" : 2 }
{ "Name" : "Jane Doe", "Times in Italy" : 1 }
我想到了这个方法,但是 MongoDB 没有输出任何东西。
db.trips.aggregate([ {$unwind:'$WentTo.Destination'},
{$match: {'Country':'Italy'}}, {$group:{_id:'$Name', Times in Italy:{$sum:1}}}])
有什么想法吗?
可能是这样的:
选项 1: $filter/$size(当没有同名的重复记录时更快更有效)
db.collection.aggregate([
{
"$addFields": {
"WentTo": {
$size: {
"$filter": {
"input": "$WentTo",
"as": "w",
"cond": {
"$eq": [
"$$w.Destination.Country",
"Italy"
]
}
}
}
}
}
},
{
$project: {
"Times in Italy": "$WentTo",
Name:1
}
}
])
解释:
- 将 addFields 与 $filter 结合使用以仅匹配以意大利为国家/地区的数组元素并使用 $size 对它们进行计数
- 将“WentTo”数组投影为“Times in Italy”并按要求命名。
选项 2: 这是对您的查询进行了小的更正,也涵盖了每个名称存在重复记录的情况,请注意更大的集合 $unwind 操作可能会影响性能并且速度慢...
db.collection.aggregate([
{
$unwind: "$WentTo"
},
{
$match: {
"WentTo.Destination.Country": "Italy"
}
},
{
$group: {
_id: "$Name",
"Times in Italy": {
$sum: 1
}
}
}
])