$ group by之后的动态键 [英] Dynamic keys after $group by

查看:151
本文介绍了$ group by之后的动态键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下收藏

{
    "_id" : ObjectId("5b18d14cbc83fd271b6a157c"),
    "status" : "pending",
    "description" : "You have to complete the challenge...",
}
{
    "_id" : ObjectId("5b18d31a27a37696ec8b5773"),
    "status" : "completed",
    "description" : "completed...",
}
{
    "_id" : ObjectId("5b18d31a27a37696ec8b5775"),
    "status" : "pending",
    "description" : "pending...",
}
{
    "_id" : ObjectId("5b18d31a27a37696ec8b5776"),
    "status" : "inProgress",
    "description" : "inProgress...",
}

我需要按status分组并动态获取status

I need to group by status and get all the keys dynamically which are in status

[
  {
    "completed": [
      {
        "_id": "5b18d31a27a37696ec8b5773",
        "status": "completed",
        "description": "completed..."
      }
    ]
  },
  {
    "pending": [
      {
        "_id": "5b18d14cbc83fd271b6a157c",
        "status": "pending",
        "description": "You have to complete the challenge..."
      },
      {
        "_id": "5b18d31a27a37696ec8b5775",
        "status": "pending",
        "description": "pending..."
      }
    ]
  },
  {
    "inProgress": [
      {
        "_id": "5b18d31a27a37696ec8b5776",
        "status": "inProgress",
        "description": "inProgress..."
      }
    ]
  }
]

推荐答案

并不是我认为这是个好主意,主要是因为我根本看不到任何汇总",而是将分组"添加到类似地,将所有内容 $push 排列成数组"status"分组密钥,然后将其转换为 $arrayToObject :

Not that I think it's a good idea and mostly because I don't see any "aggregation" here at all is that after "grouping" to add to an array you similarly $push all that content into array by the "status" grouping key and then convert into keys of a document in a $replaceRoot with $arrayToObject:

db.collection.aggregate([
  { "$group": {
    "_id": "$status",
    "data": { "$push": "$$ROOT" }
  }},
  { "$group": {
    "_id": null,
    "data": {
      "$push": {
        "k": "$_id",
        "v": "$data"
      }
    }
  }},
  { "$replaceRoot": {
    "newRoot": { "$arrayToObject": "$data" }
  }}
])

返回:

{
        "inProgress" : [
                {
                        "_id" : ObjectId("5b18d31a27a37696ec8b5776"),
                        "status" : "inProgress",
                        "description" : "inProgress..."
                }
        ],
        "completed" : [
                {
                        "_id" : ObjectId("5b18d31a27a37696ec8b5773"),
                        "status" : "completed",
                        "description" : "completed..."
                }
        ],
        "pending" : [
                {
                        "_id" : ObjectId("5b18d14cbc83fd271b6a157c"),
                        "status" : "pending",
                        "description" : "You have to complete the challenge..."
                },
                {
                        "_id" : ObjectId("5b18d31a27a37696ec8b5775"),
                        "status" : "pending",
                        "description" : "pending..."
                }
        ]
}

IF 可能是可以的,但是您实际上事先聚合了",但是在任何实际大小的集合中,所有要做的就是试图将整个集合强制为一个文档,这很可能会破坏 BSON限制为16MB ,所以我什至不建议您尝试这种方式在执行此步骤之前,无需分组"其他内容.

That might be okay IF you actually "aggregated" beforehand, but on any practically sized collection all that is doing is trying force the whole collection into a single document, and that's likely to break the BSON Limit of 16MB, so I just would not recommend even attempting this without "grouping" something else before this step.

坦率地说,以下相同的代码可以完成相同的操作,并且没有聚合技巧,也没有BSON限制问题:

Frankly, the same following code does the same thing, and without aggregation tricks and no BSON limit problem:

var obj = {};

// Using forEach as a premise for representing "any" cursor iteration form
db.collection.find().forEach(d => {
  if (!obj.hasOwnProperty(d.status))
    obj[d.status] = [];
  obj[d.status].push(d);
})

printjson(obj);

或更短一点:

var obj = {};

// Using forEach as a premise for representing "any" cursor iteration form
db.collection.find().forEach(d => 
  obj[d.status] = [ 
    ...(obj.hasOwnProperty(d.status)) ? obj[d.status] : [],
    d
  ]
)

printjson(obj);

聚合用于数据精简",而任何简单地重塑结果"却不实际减少从服务器返回的数据的方法通常都可以通过客户端代码更好地处理.无论您做什么,仍将返回所有数据,并且游标的客户端处理的开销要小得多.而且没有限制.

Aggregations are used for "data reduction" and anything that is simply "reshaping results" without actually reducing the data returned from the server is usually better handled in client code anyway. You're still returning all data no matter what you do, and the client processing of the cursor has considerably less overhead. And NO restrictions.

这篇关于$ group by之后的动态键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆