mongoose MongoDB在文档中使用集合比较数组,该数组被值和更新总数相加

kyxcudwk  于 2023-03-03  发布在  Go
关注(0)|答案(1)|浏览(123)
{
  "_id": {
    "$oid": "63fe802ce956eaeaab686ce4"
  },
  "date": {
    "$date": {
      "$numberLong": "1677542400000"
    }
  },
  "videoId": "7853f3ef01f83d82a82f67052b778a78",
  "timeds": [
    {
      "timed": 122,
      "total": 17
    },
    {
      "timed": 240,
      "total": 10
    },
    {
      "timed": 0,
      "total": 15
    },
    {
      "timed": 47,
      "total": 51
    },
    {
      "timed": 58,
      "total": 1
    }
  ],
  "uniqueViews": 13,
  "completed": 80,
  "views": 1,
  "viewed": 1,
  "left": 3
}

我有上面的文档。它有视频访问者的数据。比如有多少用户观看了视频,完成了它,并在特定的时间离开。在times数组中,timed是以秒为单位的视频时间,total是到那时为止观看视频的总访问者。我想向times数组添加更多的元素。假设我想在times中插入以下元素:

[
    {
      "timed": 122,
      "total": 41
    },
    {
      "timed": 240,
      "total": 33
    },
    {
      "timed": 450,
      "total": 15
    },
    {
      "timed": 47,
      "total": 5
    },
    {
      "timed": 96,
      "total": 1
    }
]

因此,正如你在上面的数组中看到的,我想推入时间,但在推入之前,我想检查timed属性值是否已经存在于时间中。如果它存在,那么总数应该增加,如果没有,那么推入。因此,推入上述内容后的数组将如下所示:

"timeds": [
    {
      "timed": 122,
      "total": 58
    },
    {
      "timed": 240,
      "total": 43
    },
    {
      "timed": 0,
      "total": 15
    },
    {
      "timed": 47,
      "total": 56
    },
    {
      "timed": 58,
      "total": 1
    },
    {
      "timed": 450,
      "total": 15
    },
    {
      "timed": 96,
      "total": 1
    }
  ],

因此,计时122,240,总共47个元素被递增,其他元素被推送。

{
  $set: {
    timeds: {
      $concatArrays: [
        {
          $map: {
            input: visitorDocs.visitors,
            as: "m",
            in: {
              $cond: [
                {
                  $in: [
                    "$$m.timed",
                    {
                      $map: {
                        input: "$timeds",
                        as: "visitor",
                        in: "$$visitor.timed",
                      },
                    },
                  ],
                },
                {
                  $mergeObjects: [
                    "$$m",
                    {
                      total: {
                        $add: ["$$m.total"],
                      },
                    },
                  ],
                },
                "$$m",
              ],
            },
          },
        },
        {
          $filter: {
            input: visitorDocs.visitors,
            as: "timedObj",
            cond: {
              $not: [
                {
                  $in: [
                    "$$timedObj.timed",
                    {
                      $map: {
                        input: "$timeds",
                        as: "visitor",
                        in: "$$visitor.timed",
                      },
                    },
                  ],
                },
              ],
            },
          },
        },
      ],
    },
    videoId: visitorDocs._id,
  },
  $inc: {
    uniqueViews: 45,
    left: 57,
    completed: 5,
  },
};

我试着实现上面的,但它充满了错误。

6qqygrtg

6qqygrtg1#

不确定是只想通过aggregate管道获取数据(案例1)还是想更新集合中的数据(案例2)。

案例1:

尝试此操作(请参见:https://mongoplayground.net/p/ZYXvSARHuAz):

db.collection.aggregate([
  {
    "$project": {
      timeds: {
        $concatArrays: [
          "$timeds",
          [
            {
              "timed": 122,
              "total": 41
            },
            {
              "timed": 240,
              "total": 33
            },
            {
              "timed": 450,
              "total": 15
            },
            {
              "timed": 47,
              "total": 5
            },
            {
              "timed": 96,
              "total": 1
            }
          ]
        ]
      }
    }
  },
  {
    $unwind: "$timeds"
  },
  {
    $group: {
      _id: "$timeds.timed",
      total: {
        $sum: "$timeds.total"
      }
    }
  },
  {
    "$project": {
      timed: "$_id",
      total: 1,
      _id: 0,
    }
  }
])

案例2:

我建议您在多个 idempotent mongodb查询中以编程方式分离用例,以更新timeds表:

***查询1:**添加具有重复项的timeds
***查询2:**删除重复

相关问题