I want to slice array in document according to slicingIndex key available in the same document and push into an array.
[
{
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 }
]
}
]
Output (expected):
{
"array": [
[
{ "name": 1 },
{ "name": 2 },
{ "name": 3 },
{ "name": 4 }
],
[
{ "name": 5 },
{ "name": 6 },
{ "name": 7 }
],
[
{ "name": 8 },
{ "name": 9 },
{ "name": 10 }
]
]
}
This is what aggregation i tried below but not working as expected:
db.collection.aggregate([
{
"$project": {
slicingIndex: 1,
array: {
"$map": {
"input": "$slicingIndex",
"as": "num",
"in": {
"$slice": [
"$array",
"$$num",
{
"$subtract": [
{
"$arrayElemAt": ["$slicingIndex", { "$indexOfArray": ["$slicingIndex", "$$num"] }]
},
"$$num"
]
}
]
}
}
}
}
}
])
MongoDb Playground Link : https://mongoplayground.net/p/oNzBVLRfIU0
$add
& $indexOfArray
used to take one step ahead element from current pointer in array like (n+1).
$let
: I have used it as optional to make variable reusable if needed.
$map
: To traverse array elements.
$arrayElemAt
: To get from element from array.
$subtract
: To perform operation like [ (n+1) - n ] where n is index in array.
$filter
: To filter out elements (in our case: null).
db.collection.aggregate([
{
"$project": {
array: {
"$map": {
"input": "$slicingIndex",
"as": "elem",
"in": {
"$let": {
"vars": {
//create variable that holds element one index+1 to the current index
"elemOneStepHeadToElem": {
"$arrayElemAt": [
"$slicingIndex",
{
$add: [
1,
{
"$indexOfArray": [
"$slicingIndex",
"$$elem"
]
}
]
}
]
}
},
"in": {
"$slice": [
"$array",
"$$elem",
{
"$subtract": [
"$$elemOneStepHeadToElem",
"$$elem"
]
}
]
}
}
}
}
}
}
}//remove null from array from last index
,
{
"$project": {
array: {
"$filter": {
"input": "$array",
"cond": {
$ne: [
"$$this",
null
]
}
}
}
}
}
])