【问题标题】:How to merge duplicates in an array of objects and sum a specific property in MongoDB?如何合并对象数组中的重复项并对 MongoDB 中的特定属性求和?
【发布时间】:2022-01-31 17:12:10
【问题描述】:

我正在构建一个 URL 缩短器。因此,我想在使用短 URL 访问 URL 时跟踪按日期计算的点击次数。例如:在 1 月 30 日,如果使用短 URL 访问了 3 次 URL,它将显示点击计数 5,但我的文档看起来像这样 -

{
"_id":{"$oid":"61f6322cd3e3484d97a25e7c"},
"dayWiseClicks":
[{"date":"01/30/2022","dailyClicks":1,"_id":{"$oid":"61f66ff95fadc3e9f01b0d34"}},
{"date":"01/30/2022","dailyClicks":1,"_id":{"$oid":"61f66ffd5fadc3e9f01b0d38"}},
{"date":"01/30/2022","dailyClicks":1,"_id":{"$oid":"61f66fff5fadc3e9f01b0d3c"}}]
}

我希望我的文档如下所示:

{
"_id":{"$oid":"61f6322cd3e3484d97a25e7c"},
"dayWiseClicks":
[{"date":"01/30/2022","dailyClicks":3,"_id":{"$oid":"61f66ff95fadc3e9f01b0d34"}}]
}

如何使用 MongoDB 聚合管道实现此目的?

更新 这是完整的架构:

{
    merchant_name: String,
    store_id: String,
    original_url: String,
    url_hash: String,
    subdomain: String,
    // password: String,
    totalClicks: {
      type: Number,
      default: 0,
    },
    igClicks: {
      type: Number,
      default: 0,
    },
    fbClicks: {
      type: Number,
      default: 0,
    },
    directClicks: {
      type: Number,
      default: 0,
    },
    dayWiseClicks: [
      {
        date: {
          type: String,
          default: moment(new Date()).format("L"),
        },
        dailyClicks: {
          type: Number,
          default: 0,
        },
      },
    ],
    desktopClicks: {
      device: { type: String, default: "Desktop" },
      clicks: { type: Number, default: 0 },
    },
    mobileClicks: {
      device: { type: String, default: "Mobile" },
      clicks: { type: Number, default: 0 },
    },
  },
  { timestamps: true }

聚合完成后,我希望我的文档如下所示:

{
    "_id": {
      "$oid": "61f7a3b83dcebb77b05bd180"
    },
    "desktopClicks": {
      "device": "Desktop",
      "clicks": 5
    },
    "mobileClicks": {
      "device": "Mobile",
      "clicks": 0
    },
    "totalClicks": 5,
    "igClicks": 0,
    "fbClicks": 0,
    "directClicks": 5,
    "dayWiseClicks": [
      {
        "date": "01/31/2022",
        "dailyClicks": 5,
        "_id": {
          "$oid": "61f7a3fe5bd4f779cc53f697"
        }
      }
    ],
    "merchant_name": "Akash DTH",
    "store_id": "3333",
    "url_hash": "OGZhYTI",
    "subdomain": "",
    "original_url": "https://akashdth.com/",
    "createdAt": {
      "$date": "2022-01-31T08:54:16.472Z"
    },
    "updatedAt": {
      "$date": "2022-01-31T09:03:55.925Z"
    },
    "__v": 0
  }

【问题讨论】:

  • 你能分享以上集合的架构吗?
  • @cEeNiKc 我已经添加了架构
  • 我添加了一个可能的答案,您在上面的预期文档只显示了一个dayWiseClicks._id,发布的答案只返回第一个

标签: javascript node.js mongodb mongoose


【解决方案1】:

试试

https://mongoplayground.net/p/osWlBuYy0NZ

db.collection.aggregate([
  {
    $unwind: {
      "path": "$dayWiseClicks"
    }
  },
  {
    $group: {
      _id: {
        "oid": "$_id",
        "date": "$dayWiseClicks.date"
      },
      "dailyClicks": {
        $sum: "$dayWiseClicks.dailyClicks"
      },
      "originalDayWiseClicks": {
        $push: "$dayWiseClicks"
      }
    }
  },
  {
    "$addFields": {
      "dayWiseClicks": [
        {
          "date": "$_id.date",
          "dailyClicks": "$dailyClicks",
          "_id": {
            "$first": "$originalDayWiseClicks._id"
          }
        }
      ]
    }
  },
  {
    "$project": {
      _id: "$_id.oid",
      "dayWiseClicks": 1
    }
  }
])

如果您不需要嵌套的dayWiseClicks 或第一个dayWiseClicks._id

可以简化为:

https://mongoplayground.net/p/Zc9whjiLWdt

db.collection.aggregate([
  {
    $unwind: {
      "path": "$dayWiseClicks"
    }
  },
  {
    $group: {
      _id: {
        "oid": "$_id",
        "date": "$dayWiseClicks.date"
      },
      "dailyClicks": {
        $sum: "$dayWiseClicks.dailyClicks"
      }
    }
  },
  {
    $addFields: {
      "_id": "$_id.oid",
      "date": "$_id.date",
      
    }
  }
])

【讨论】:

  • 如何将聚合输出保存在数据库中?我在这个集合中还有其他字段。我想将聚合输出与所有这些字段一起保存。我在主帖中添加了整个架构和示例文档。
  • 可能类似于:mkyong.com/mongodb/…
猜你喜欢
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
相关资源
最近更新 更多