You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合框架:计算数组元素权重并跳过末尾连续C元素

Fixing MongoDB Aggregation to Handle Trailing Consecutive "C" Values

Got it, let's get your aggregation logic sorted to properly handle those trailing consecutive "C" elements. The core issue with your original code is that it only accounts for a single trailing "C"—we need to first identify how many consecutive "C"s are at the end of the array, then target the last non-"C" element correctly.

First, Let's Recap Your Weight Rules

  • If the last element isn't "C": Assign weight 1.0 to the final element, 0 to all others
  • If the last element is "C": Skip all consecutive trailing "C"s, assign weight 1 to the last non-"C" element, 0 to everything else
  • If the array has only 1 element: Assign weight 1 to that element

Corrected Aggregation Code

db.col.aggregate([
  {
    $addFields: {
      // Extract just the values from myArray to simplify processing
      valueArray: { $map: { input: "$myArray", as: "elem", in: "$$elem.value" } },
      // Reverse the value array to find trailing Cs from the start
      reversedValues: { $reverseArray: "$valueArray" }
    }
  },
  {
    $addFields: {
      // Find the index of the first non-C in the reversed array (this is the count of trailing Cs)
      trailingCCount: {
        $indexOfArray: [
          "$reversedValues",
          { $not: { $eq: "C" } }
        ]
      },
      // Handle edge case: if all elements are C, trailingCCount will be -1, so set to array length
      adjustedTrailingCCount: {
        $cond: [
          { $eq: ["$trailingCCount", -1] },
          { $size: "$valueArray" },
          "$trailingCCount"
        ]
      }
    }
  },
  {
    $addFields: {
      // Calculate the index of the last non-C element in the original array
      targetIndex: {
        $subtract: [
          { $size: "$myArray" },
          "$adjustedTrailingCCount",
          1
        ]
      }
    }
  },
  {
    $addFields: {
      // Build the final weighted array
      myArray: {
        $map: {
          input: "$myArray",
          as: "elem",
          in: {
            value: "$$elem.value",
            weight: {
              $cond: [
                { $eq: [{ $indexOfArray: ["$myArray", "$$elem"] }, "$targetIndex"] },
                1,
                0
              ]
            }
          }
        }
      }
    }
  },
  // Clean up the temporary fields we created
  {
    $project: {
      valueArray: 0,
      reversedValues: 0,
      trailingCCount: 0,
      adjustedTrailingCCount: 0,
      targetIndex: 0
    }
  }
])

How This Works

Let's walk through the logic with your sample documents:

For Document 1 (myArray: [C, A, C, B, A, A])

  1. valueArray becomes ["C", "A", "C", "B", "A", "A"]
  2. reversedValues is ["A", "A", "B", "C", "A", "C"]
  3. trailingCCount is 0 (first element in reversed array is non-C)
  4. targetIndex is 6 - 0 - 1 = 5 (the last element in the original array)
  5. The $map assigns weight 1 to index 5, 0 to others—matches your expected result.

For Document 2 (myArray: [A, C, B, C, C])

  1. valueArray becomes ["A", "C", "B", "C", "C"]
  2. reversedValues is ["C", "C", "B", "C", "A"]
  3. trailingCCount is 2 (first non-C is at index 2 in reversed array)
  4. targetIndex is 5 - 2 - 1 = 2 (the "B" element in original array)
  5. The $map assigns weight 1 to index 2, 0 to others—perfect match for your expected result.

Edge Case: All Elements Are C (myArray: [C, C, C])

If every element is "C", the code will set adjustedTrailingCCount to the array length, resulting in targetIndex being -1. The $map will assign 0 to all elements—this is a reasonable default since there's no non-C element to apply the weight rule to.

内容的提问来源于stack exchange,提问作者Dr. Mza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:16:33