【问题标题】:Querying the total number of elements in nested arrays - embed documents MongoDB查询嵌套数组中元素的总数 - 嵌入文档 MongoDB
【发布时间】:2017-06-29 11:56:23
【问题描述】:

我的收藏中有以下文档:

{
  _id: 1,
  activities: [
    {
      activity_id: 1,
      travel: [
        {
          point_id: 1,
          location: [-76.0,19.1]
        },
        {
          point_id: 2,
          location: [-77.0,19.3]
        }
      ]
    },
    {
      activity_id: 2,
      travel: [
        {
          point_id: 3,
          location: [-99.3,18.2]
        }
      ]
    }
  ]
},
{
  _id: 2,
  activities: [
    {
      activity_id: 3,
      travel: [
        {
          point_id: 4,
          location: [-75.0,11.1]
        }
      ]
    }
  ]
}

我可以得到活动的总数,如下:

db.mycollection.aggregate(
  {$unwind: "$activities"}, 
  {$project: {count:{$add:1}}}, 
  {$group: {_id: null, number: {$sum: "$count" }}}
)

我得到(3 个活动):

{ "result" : [ { "_id" : null, "number" : 3 } ], "ok" : 1 }

问题:我怎样才能得到所有游记中的元素总数?

预期结果: 4 元素

这些是:

{
  point_id: 1,
  location: [-76.0,19.1]
},
{
  point_id: 2,
  location: [-77.0,19.3]
},
{
  point_id: 3,
  location: [-99.3,18.2]
},
{
  point_id: 4,
  location: [-75.0,11.1]
}

【问题讨论】:

  • 实际上,这过去和现在仍然像db.mycollection.aggregate({ "$group": { "_id": null, "total": { "$sum": { "$sum": { "$map": { "input": "$activities", "as": "a", "in": { "$size": "$$a.travel" } } } } } }}) 一样简单。这是因为$sum 可以直接与数组一起使用,也可以作为 MongoDB 3.2 以来的累加器。根据您自己删除的答案,您此时的 MongoDB 版本似乎比那要旧得多。

标签: mongodb mongodb-query aggregation-framework nosql


【解决方案1】:

您可以使用 double $unwind 轻松转换文档

例如

db.collection.aggregate([
  {$unwind: "$activities"},
  {$unwind: "$activities.travel"},
  {$group:{
    _id:null, 
    travel: {$push: {
      point_id:"$activities.travel.point_id", 
      location:"$activities.travel.location"}}
  }},
  {$project:{_id:0, travel:"$travel"}}
])

这将发出非常接近您所需的输出格式:

{ 
    "travel" : [
        {
            "point_id" : 1.0, 
            "location" : [
                -76.0, 
                19.1
            ]
        }, 
        {
            "point_id" : 2.0, 
            "location" : [
                -77.0, 
                19.3
            ]
        }, 
        {
            "point_id" : 3.0, 
            "location" : [
                -99.3, 
                18.2
            ]
        }, 
        {
            "point_id" : 4.0, 
            "location" : [
                -75.0, 
                11.1
            ]
        }
    ]
}

更新:

如果您只想知道整个集合中的旅行证件总数,

试试:

db.collection.aggregate([
  {$unwind: "$activities"},
  {$unwind: "$activities.travel"},
  {$group: {_id:0, total:{$sum:1}}}
])

它将打印:

{ 
    "_id" : NumberInt(0), 
    "total" : NumberInt(4)
}

更新 2:

OP 希望根据聚合框架中的某些属性过滤文档。这是一种方法:

db.collection.aggregate([
  {$unwind: "$activities"},
  {$match:{"activities.activity_id":1}},
  {$unwind: "$activities.travel"},
  {$group: {_id:0, total:{$sum:1}}}
])

它将打印(基于示例文档):

{ "_id" : 0, "total" : 2 }

【讨论】:

  • 是否可以添加参数{$match: { "activities.activity_id": 1}} 这样我就可以获得特定活动的旅行列表? ....怎么做?
  • 确实可以。见 $match
  • 是的,但是.....这不起作用,请参阅Filtering embedded documents in MongoDB ...。我想我将不得不使用关系表而不是嵌入对象
  • 我相信它有效。目前我无法访问机器,但会尽快更新。
  • 我看错了,$match$unwindparameters 的顺序很关键
猜你喜欢
  • 2019-10-09
  • 2021-04-14
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2021-08-07
  • 2018-03-09
  • 2019-02-20
  • 2015-08-30
相关资源
最近更新 更多