繁体   English   中英

$ group by之后的动态键

[英]Dynamic keys after $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

[
  {
    "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..."
      }
    ]
  }
]

并不是说我认为这是个好主意,主要是因为我根本看不到任何“聚合”,是在将“分组”添加到数组后,您也同样通过"status"分组键$push所有内容$push入数组中然后使用$arrayToObject将其转换为$replaceRoot文档的键:

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..."
                }
        ]
}

如果您实际上事先进行了“聚合”,那可能就可以了,但是在任何实际大小的集合上,所有要做的就是将整个集合强制到一个文档中,这很可能会超出BSON限制16MB ,所以我只是不建议在此步骤之前,甚至尝试不进行“分组”操作。

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

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);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM