簡體   English   中英

如何按多個字段對子文檔數組進行分組?

[英]How to group an array of subdocuments by multiple fields?

我花了一天的大部分時間在這上面,現在沒有想法了。 這是我的收藏:

[
  {
    "_id": "ID_XXX",
    "logs": [
      {
        "lead_id": 123,
        "list_id": "list_44",
        "order_id": "order_1"
      },
      {
        "lead_id": 124,
        "list_id": "list_44",
        "order_id": "order_2"
      }
    ]
  },
  {
    "_id": "ID_YYY",
    "logs": [
      {
        "lead_id": 125,
        "list_id": "list_44",
        "order_id": "order_2"
      },
      {
        "lead_id": 126,
        "list_id": "list_44",
        "order_id": "order_2"
      },
      {
        "lead_id": 127,
        "list_id": "list_44",
        "order_id": "order_3"
      },
      {
        "lead_id": 128,
        "list_id": "list_66",
        "order_id": "order_3"
      }
    ]
  }
]

我只是想獲取list_idorder_id的計數,同時保留它們所在文檔的_id 。這是我想要的 output:

[
  {
    "_id": "ID_XXX",
    "counts": [
      {
        "lists": {"list_44": 2},
      },
      {
        "orders": {"order_1": 1, "order_2": 1}
      }
    ]
  },
  {
    "_id": "ID_YYY",
    "counts": [
      {
        "lists": {"list_44": 3, "list_66": 1},
      },
      {
        "orders": {"order_2": 2, "order_3": 2}
      }
    ]
  }
]

我嘗試了太多的聚合變體,無法在此處列出,但最新的是:

db.collection.aggregate([
  {
    $unwind: "$logs"
  },
  {
    $group: {
      _id: "$_id",
      lists: {
        $push: "$logs.list_id"
      },
      orders: {
        $push: "$logs.order_id"
      }
    }
  }
])

這並沒有給我想要的東西。 誰能指出我正確的方向? 這是操場鏈接: https://mongoplayground.net/p/f-jk7lbSrJ0

  • $reduce迭代logs循環,使用$objectToArray objectToArray 將logs object 轉換為 k(key) v(value) 格式的數組, $concatArrays使用$reduce reduce 中的 initialValue,
  • 上面的$filter將結果減少為輸入並從logs中過濾所需字段
  • $unwind解構logs數組
db.collection.aggregate([
  {
    $addFields: {
      logs: {
        $filter: {
          input: {
            $reduce: {
              input: "$logs",
              initialValue: [],
              in: { $concatArrays: ["$$value", { $objectToArray: "$$this" }] }
            }
          },
          cond: { $in: ["$$this.k", ["list_id", "order_id"]] }
        }
      }
    }
  },
  { $unwind: "$logs" },
  • $group by _idlogs object 並使用$sum獲取總數
  {
    $group: {
      _id: {
        _id: "$_id",
        logs: "$logs"
      },
      counts: { $sum: 1 }
    }
  },
  • $group by _id如果logs.klist_id則創建lists數組,否則返回 k 和 v 格式$$REMOVE ,與訂單相同,在order_id的基礎上創建orders數組
  • $addFieldslists數組從 k 和 v 格式轉換為 object 格式,與訂單數組and same as for
  {
    $group: {
      _id: "$_id._id",
      lists: {
        $push: {
          $cond: [
            { $eq: ["$_id.logs.k", "list_id"] },
            {
              k: "$_id.logs.v",
              v: "$counts"
            },
            "$$REMOVE"
          ]
        }
      },
      orders: {
        $push: {
          $cond: [
            { $eq: ["$_id.logs.k", "order_id"] },
            {
              k: "$_id.logs.v",
              v: "$counts"
            },
            "$$REMOVE"
          ]
        }
      }
    }
  },
  {
    $addFields: {
      lists: { $arrayToObject: "$lists" },
      orders: { $arrayToObject: "$orders" }
    }
  }
])

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM