在 MondoDB 中:从切片索引数组中切片对象数组并通过聚合推入数组

问题描述 投票:0回答:1

我想根据同一文档中可用的 slicingIndex 键对文档中的数组进行切片并推入数组中。

[
  {
    slicingIndex: [0, 4, 7, 10],
    array: [
      { name: 1 },
      { name: 2 },
      { name: 3 },
      { name: 4 },
      { name: 5 },
      { name: 6 },
      { name: 7 },
      { name: 8 },
      { name: 9 },
      { name: 10 }
    ]
  }
]

输出(预期):

{
  "array": [
    [
      { "name": 1 },
      { "name": 2 },
      { "name": 3 },
      { "name": 4 }
    ],
    [
      { "name": 5 },
      { "name": 6 },
      { "name": 7 }
    ],
    [
      { "name": 8 },
      { "name": 9 },
      { "name": 10 }
    ]
  ]
}

这是我在下面尝试的聚合,但没有按预期工作:

db.collection.aggregate([
  {
    "$project": {
      slicingIndex: 1,
      array: {
        "$map": {
          "input": "$slicingIndex",
          "as": "num",
          "in": {
            "$slice": [
              "$array",
              "$$num",
              {
                "$subtract": [
                  {
                    "$arrayElemAt": ["$slicingIndex", { "$indexOfArray": ["$slicingIndex", "$$num"] }]
                  },
                  "$$num"
                ]
              }
            ]
          }
        }
      }
    }
  }
])
arrays mongodb aggregation-framework slice
1个回答
0
投票
  1. 通过压缩

    slicingIndex
    为切片的索引对创建两个数组。对于起始索引 - 取
    n
    元素,其中 n = 大小减 1。对于结束索引,使用
    minus n
    表示
    slice
    从末尾开始。

    • 这给出了数组
      startIndexes: [0, 4, 7]
      endIndexes: [4, 7, 10]
  2. 然后将这两个压缩在一起以获得开始和结束索引对。

    • sliceIdxPairs
      [[0, 4], [4, 7], [7, 10]]
  3. 但是由于

    $slice
    聚合的参数是
    position
    (起始索引)和
    n
    (元素数量),我们需要的是从每个中的
    endIndex
    中减去
    startIndex
    成对。

    • sliceParams
      [[0, 4], [4, 3], [7, 3]]
  4. 最后,

    $map
    sliceParams
    中的数字对,并将它们与
    $slice
    字段上的
    array
    一起使用。

db.collection.aggregate([
  {
    $project: {
      array: 1,
      startIndexes: {
        $slice: [
          "$slicingIndex",
          {
            $subtract: [
              {
                $size: "$slicingIndex"
              },
              1
            ]
          }
        ]
      },
      endIndexes: {
        $slice: [
          "$slicingIndex",
          {
            $multiply: [
              {
                $subtract: [
                  {
                    $size: "$slicingIndex"
                  },
                  1
                ]
              },
              -1
            ]
          }
        ]
      }
    }
  },
  {
    $project: {
      array: 1,
      sliceIdxPairs: {
        $zip: {
          inputs: [
            "$startIndexes",
            "$endIndexes"
          ]
        }
      }
    }
  },
  {
    $project: {
      array: 1,
      sliceParams: {
        $map: {
          input: "$sliceIdxPairs",
          as: "ip",
          in: [
            {
              $first: "$$ip"
            },
            {
              $subtract: [
                {
                  $last: "$$ip"
                },
                {
                  $first: "$$ip"
                }
              ]
            }
          ]
        }
      }
    }
  },
  {
    $project: {
      array: {
        $map: {
          input: "$sliceParams",
          as: "pair",
          in: {
            $slice: [
              "$array",
              {
                $first: "$$pair"
              },
              {
                $last: "$$pair"
              }
            ]
          }
        }
      }
    }
  }
])

蒙戈游乐场

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.