计算不同的子文档字段并输出为命名键

2024-04-09

在 MongoDB 中,如果我有一个如下所示的集合,

{
    "auctionId" : 22,
    "startDt" : "2017-08-28T06:00:00.000Z",
    "endDt" : "2017-09-04T06:00:00.000Z",
    "status" : "Open",
    "pickupDt" : "2017-09-07T06:00:00.000Z",
    "itmLst" : 
    [ 
        {
            "itemId" : 1,
            "location" : "Open",
            "currentBid" : 13.0,
            "highBidder" : 1897,
            "bidCnt" : 4,
            "catgegory" : "ANTIQUES"
             ...

我如何使用聚合函数查询它,以检索uctionId = 22的不同类别的计数,按itmLst.category分组,这样它将返回一个如下所示的结果集:

{
    "ANTIQUES": 56,
    "TOOLS": 89,
    "JEWLRY": 45,
    ...
}

这里的基本情况是使用.aggregate() https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/ with $unwind https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/因为您需要访问数组中的值作为分组键,当然$group https://docs.mongodb.com/manual/reference/operator/aggregation/group/因为这就是你“分组”事物的方式:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }}
])

这将为您提供如下输出:

{ "_id": "ANTIQUES", "count": 56 }
{ "_id": "TOOLS", "count": 89 }
{ "_id": "JEWLRY", "count":  45 }

现在你真的应该学会忍受这一点,因为默认光标格式的“列表”是一件好事,它自然是可迭代的。另外,恕我直言,命名键本身并不适合数据表示,并且您通常需要可迭代列表中的公共属性。

如果您确实打算使用单一命名键输出,那么您将需要 MongoDB 3.4.4 或更高版本才能访问$arrayToObject https://docs.mongodb.com/manual/reference/operator/aggregation/arrayToObject/这将允许您使用值作为键的名称,当然$replaceRoot https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/为了使用该表达式输出作为新文档来生成:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": null,
    "data": { "$push": { "k": "$_id", "v": "$count" } }
  }},
  { "$replaceRoot": {
    "newRoot": {
      "$arrayToObject": "$data"
    }
  }}
])

或者,如果您没有该选项,那么您应该在代码中转换光标输出:

db.collection.aggregate([
  { "$match": { "auctionId": 22 } },
  { "$unwind": "$itmLst" },
  { "$group": {
    "_id": "$itmLst.category",
    "count": { "$sum": 1 }
  }}
]).toArray().reduce((acc,curr) => 
  Object.assign(acc,{ [curr._id]: curr.count }),
  {}
)

两者都合并为一个对象,其中包含原始聚合输出中的命名键:

{
    "ANTIQUES": 56,
    "TOOLS": 89,
    "JEWLRY": 45,
    ...
}

这表明原始输出结果确实足够了,并且通常您希望在使用光标输出的代码中完成这种“最终重塑”,如果您真的需要这种重塑,因为基本的无论如何,所需的数据已返回。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算不同的子文档字段并输出为命名键 的相关文章

随机推荐