代码之家  ›  专栏  ›  技术社区  ›  robert_gonzalez

MongoDB:统计子文档中要素的出现次数

  •  0
  • robert_gonzalez  · 技术社区  · 2 年前

    我有一个mongoDB数据库,叫做 trips 结构如下:

    {'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 回复  |  直到 2 年前
        1
  •  1
  •   R2D2    2 年前

    可能是这样的:

    选项1: $筛选器/$大小(如果没有同名的重复记录,则更快更有效)

    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. 将“WentTo”数组投影为“Times in Italy”,并根据要求命名。

    Playground 1

    选项2: 这是您的查询,有一些小的更正,也涵盖了每个名称都有模糊记录的情况,请注意,对于较大的集合$展开操作可能会影响性能且速度较慢。。。

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

    Playground 2