mongodb aggregation 获取数组中负序的最大个数

mongodb aggregation get max number of negative sequence in array

我需要通过聚合从数组中获取负序列的最大计数,示例文档:

  {
  "id": 1,
   x: [ 1,1,-1,-1,1,1,1,-1,-1,-1,-1]
 },
 {
"id": 2,
  x: [ 1,-1,-1,1,1,1,-1 ]
 }

预期结果:

 {"id": 1,x:4},
 {"id": 2,x:2}

请指教?

您可以使用 $reduce to iterate the array and $cond 来应用您的逻辑(连续否定)

载体格式

     {
        previous: // previous value to compare for continuity 
        acc: // number of consecutive negatives in the current sequence
        max: // length of the longest sequence
      }

$let 是为了记忆当前累加器以在最大计算中重用。它是可选的但方便:

db.collection.aggregate([
  {
    "$set": {
      "x": {
        "$reduce": {
          "input": "$x",
          "initialValue": {
            previous: 0,
            acc: 0,
            max: 0
          },
          "in": {
            $let: {
              vars: {
                result: {
                  "$cond": {
                    "if": {
                      "$and": [
                        {
                          "$lt": [
                            "$$this",
                            0
                          ]
                        },
                        {
                          "$lt": [
                            "$$value.previous",
                            0
                          ]
                        }
                      ]
                    },
                    "then": {
                      "$add": [
                        "$$value.acc",
                        1
                      ]
                    },
                    "else": {
                      "$cond": {
                        "if": {
                          "$lt": [
                            "$$this",
                            0
                          ]
                        },
                        "then": 1,
                        "else": 0
                      }
                    }
                  }
                }
              },
              in: {
                previous: "$$this",
                acc: "$$result",
                max: {
                  "$cond": {
                    "if": {
                      $gt: [
                        "$$value.max",
                        "$$result"
                      ]
                    },
                    "then": "$$value.max",
                    "else": "$$result"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$set": {
      x: "$x.max"
    }
  }
])

mongoplayground.net 上试用。

这是另一种方法。总体思路是将序列 $reduce 到一个字符串,然后 $split 使数组填充每个 运行 的字符串。然后将字符串数组映射到字符串长度数组,然后取最大值

db.collection.aggregate({
  "$project": {
    "_id": 0,
    "id": 1,
    "x": {
      "$max": {
        "$map": {
          "input": {
            $split: [
              {
                "$reduce": {
                  "input": "$x",
                  "initialValue": "",
                  "in": {
                    $concat: [
                      "$$value",
                      {
                        "$cond": [
                          {
                            "$gt": [
                              "$$this",
                              0
                            ]
                          },
                          "p",
                          "n"
                        ]
                      }
                    ]
                  }
                }
              },
              "p"
            ]
          },
          "in": {
            "$strLenBytes": "$$this"
          }
        }
      }
    }
  }
})

mongoplayground.net 上试用。