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
   }
 }
])

解释:

  1. 将 addFields 与 $filter 结合使用以仅匹配以意大利为国家/地区的数组元素并使用 $size
  2. 对它们进行计数
  3. 将“WentTo”数组投影为“Times in Italy”并按要求命名。

Playground 1

选项 2: 这是对您的查询进行了小的更正,也涵盖了每个名称存在重复记录的情况,请注意更大的集合 $unwind 操作可能会影响性能并且速度慢...

 db.collection.aggregate([
 {
   $unwind: "$WentTo"
 },
 {
  $match: {
    "WentTo.Destination.Country": "Italy"
  }
 },
 {
  $group: {
    _id: "$Name",
      "Times in Italy": {
        $sum: 1
    }
   }
  }
 ])

Playground 2