I have data in a MongoDB collection that looks something like this:
[
{
"_id": 1,
"type": "big",
"fields": [11, 12, 13],
"items": [21, 22, 23]
},
{
"_id": 2,
"type": "small",
"fields": [14, 15],
"items": [24, 25]
},
{
"_id": 3,
"type": "small",
"fields": [],
"items": [41, 42]
},
{
"_id": 4,
"type": "small",
"fields": [31, 32, 33],
"items": []
}
]
I have been tasked with returning data according to a procedure like this:
For each document in the collection, obtain 1 value from its
fields(if there are any), and 1 value itsitems(if there are any). Concatenate all of the results in a single array.
One might summarize this as selecting data in "round robin" fashion from two arrays held in each document.
How would I achieve this in a MongoDB aggregation query? This logic is not hard to implement in the client that connects to the Mongo server, but I would like to let Mongo take care of pagination (with $skip and $limit). I am using MongoDB 4.4.
The resulting data would look something like this:
[
{
"value": 11,
"type": "field",
"fromId": 1
},
{
"value": 21,
"type": "item",
"fromId": 1
},
{
"value": 14,
"type": "field",
"fromId": 2
},
{
"value": 24,
"type": "item",
"fromId": 2
},
{
"value": 41,
"type": "item",
"fromId": 3
},
{
"value": 31,
"type": "field",
"fromId": 4
},
]
If I understand your question right; this should be a workable pipe. To implement a random functionality, you would simply adjust the index passed to $arrayElemAt
https://mongoplayground.net/p/PPXV6fTSwHP
db.collection.aggregate([
{$project: {
types: [
{type: "field", values: "$fields"},
{type: "item", values: "$items"}
]
}},
{$unwind: '$types'},
{$project: {
_id: 0,
value: {$arrayElemAt: ['$types.values', 0]},
type: '$types.type',
fromId: '$_id'
}},
{$match: {
value: {$exists: true}
}}
])
Randomizing would look something like this: https://mongoplayground.net/p/qi1Ud53J6yv
db.collection.aggregate([
{$project: {
types: [
{type: "field", values: "$fields"},
{type: "item", values: "$items"}
]
}},
{$unwind: '$types'},
{$project: {
_id: 0,
value: {$arrayElemAt: [
'$types.values',
{$floor: {$multiply: [{$rand: {}}, {$size: '$types.values'}]}}
]},
type: '$types.type',
fromId: '$_id'
}},
{$match: {
value: {$exists: true}
}}
])