【问题标题】:How to group by the first element of an array?如何按数组的第一个元素分组?
【发布时间】:2015-10-28 10:27:31
【问题描述】:

我使用的文档如下:

{
    "foo" : { "objectid" : "39", "stuff" : "65" },
    "yearpublished" : ["1979"],
    "bar" : "1263"
}

yearpublished 是一个数组,我想按此数组中的第一个值对我的集合进行分组,然后计算相关文档的数量。

我已经写了这个查询:

db.foobar.aggregate([
    { $group : {
        _id : '$yearpublished',
        count: { $sum: 1 }
    }}
])

然后得到:

{
    "result" : [ 
        { "_id" : ["1923"], "count" : 1.0000000000000000 }, 
        { "_id" : ["1864"], "count" : 1.0000000000000000 }
    ]
}

但我正在寻找这种结果(即仅第一个元素):

{
    "result" : [ 
        { "_id" : "1923", "count" : 1.0000000000000000 }, 
        { "_id" : "1864", "count" : 1.0000000000000000 }
    ]
}

我也尝试过_id : { $first: '$yearpublished.0' },_id : { $first: '$yearpublished[0]' },,但均未成功。

如何按数组 yearpublished 的第一个元素进行分组?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    不幸的是,目前唯一的方法是在处理$unwind 后从数组中提取$first 元素。那你当然得再次$group

    db.foobar.aggregate([
        { "$unwind": "$yearpublished" },
        { "$group": {
            "_id": "$_id",
            "yearpublished": { "$first": "$yearpublished" }
        }},
        { "$group": {
            "_id": "$yearpublished",
            "count": { "$sum": 1 }
        }}
    ])
    

    这是从数组中获取“第一个”元素的唯一当前方法,方法是解构它并使用运算符获取条目。

    未来版本将具有$arrayElemAt,它可以在单个阶段内按索引执行此操作:

    db.foobar.aggregate([
        { "$group": {
            "_id": { "$arrayElemAt": [ "$yearpublished", 0 ] },
            "count": { "$sum": 1 }
        }}
    ])
    

    但目前聚合框架不处理“点表示法”索引的使用,例如.find() 的标准“投影”会处理,也不会处理,因此有了新的操作。

    【讨论】:

      【解决方案2】:

      Mongo 4.4 开始,聚合运算符$first 可用于访问数组的第一个元素。

      在我们的情况下,在小组赛阶段:

      // { "yearpublished": ["1979", "2003"] }
      // { "yearpublished": ["1954", "1979"] }
      // { "yearpublished": ["1954"] }
      db.collection.aggregate([
        { $group: {
          "_id": { $first: "$yearpublished" },
          "count": { $sum: 1 }
        }}
      ])
      // { "_id" : "1954", "count" : 2 }
      // { "_id" : "1979", "count" : 1 }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-16
        • 2023-03-03
        • 2019-11-25
        • 2023-04-01
        相关资源
        最近更新 更多