当标志update设置为true时,我有以下流水线根据score计算排名(排序):

  const pipeline = [
    {$match: {"score": {$gt: 0}, "update": true}},
    {$setWindowFields: {sortBy: {"score": -1}, output: {"rank": {$denseRank: {}}}}},
    {$merge: {into: "ranking"}}
  ];
  
  await ranking_col.aggregate(pipeline).toArray();

我接下来要做的是在update标志设置为false时将rank设置为0:

ranking_col.updateMany({"update": false}, {$set: {"rank": parseInt(0, 10)}});

我的其中一个文档是这样的:

{
  "_id": "7dqe1kcA7R1YGjdwHsAkV83",
  "score": 294,
  "update": false,
  "rank": 0,
}

我希望避免额外的updateMany调用,并在管道内执行相同的调用.当时MongoDB的支持告诉我这样使用$addFields标志:

const pipeline = [
    {$match: {"score": {$gt: 0}, "update": true}},
    {$setWindowFields: {sortBy: {"score": -1}, output: {"rank": {$denseRank: {}}}}},
    {$addFields: {rank: {$cond: [{$eq: ['$update', false]},parseInt(0, 10),'$rank']}}},
    {$merge: {into: "ranking"}}
  ];

这在我的阿特拉斯触发器中不起作用. 你能纠正我的语法吗?或者告诉我一个好的方法?

推荐答案

这个聚合管道不是特别高效("$setWindowFields"个工作中有相当多的工作被丢弃--下面有更多关于这方面的 comments ),但我认为它能做您想要的事情.请判断以确保它是正确的,因为我不完全了解Collection ,它的用途等.

注:此聚合管道效率不是很高,因为:

  1. 它处理每一份文件.不存在用于过滤文档的前"$match".
  2. 由于1.,"$setWindowFields"必须对"update": false个分区和"$and": ["update": true, {"$lte": ["score", 0]}]个文档进行"partitionBy": "$update"和排序/排名,即使它是无关的.
  3. 只需将"update": false"分区的"rank"设置为0,然后从"$merge"中排除所有"$and": ["update": true, {"$lte": ["score", 0]}]个文档,所有不相关的工作都会被丢弃.

在大型集合中,最初的两步更新可能会更高效.

db.ranking.aggregate([
  {
    "$setWindowFields": {
      "partitionBy": "$update",
      "sortBy": {"score": -1},
      "output": {
        "rank": {"$denseRank": {}}
      }
    }
  },
  {
    "$set": {
      "rank": {
        "$cond": [
          "$update",
          "$rank",
          0
        ]
      }
    }
  },
  {
    "$match": {
      "$expr": {
        "$not": [{"$and": ["$update", {"$lte": ["$score", 0]}]}]
      }
    }
  },
  {"$merge": "ranking"}
])

试穿一下mongoplayground.net号.

Mongodb相关问答推荐

如何将空值单独分组?

无法配置数据源:未指定url属性,无法为 MongoDb 配置嵌入数据源

Mongo 将一个数组链接到另一个数组

如何判断 mongodb 聚合,该文档具有键,该键是一个数组,其第二个元素是否存在?

在延迟函数中重用 context.WithTimeout

Mongoose 更新不同类型的记录

有没有办法在 Prisma for MongoDB 的模式中显式声明 int32?

在 MongoDB 中,如何使用对当前值进行操作的函数来更新嵌套文档的值?

Mongoose $inc 枚举验证失败

使用 mongodb 时是否需要规范化数据库?

如何将 json 字符串编组到 bson 文档以写入 MongoDB?

使用 homebrew 和 Xcode 8.1.1 安装 Mongodb 失败

MongoDB映射/减少多个集合?

在 Ubuntu 14.04 中安装 MongoDB 失败

如何在 mongo JavaScript shell 中中止查询

如何按季度分组日期?

MongoDB聚合排序不起作用

在 MongoDB 中插入或更新许多文档

Mongodb 查找除一两个条件之外的所有内容

mongodb & max connections最大连接数