आप एकत्रीकरण पाइपलाइन के नीचे कोशिश कर सकते हैं।
नोट मर्जऑब्जेक्ट
एग्रीगेशन ऑपरेटर 3.5.6 +
. में उपलब्ध है डेवलपमेंट रिलीज़ जिसे आगामी 3.6
. में रोल किया जाएगा रिलीज।
db.collection.find();
{
"data" : [
[
{
"movie" : "starwars",
"showday" : "monday"
},
{
"movie" : "batman",
"showday" : "thursday"
},
{
"movie" : "sleepless",
"showday" : "tuesday"
}
],
[
{
"actor" : "angelina",
"location" : "new york"
},
{
"actor" : "jamie",
"location" : "california"
},
{
"actor" : "mcavoy",
"location" : "arizona"
}
]
]
}
सशर्त अभिव्यक्ति का उपयोग करके एकत्रीकरण।
aggregate({
$project: {
cp: {
$reduce: {
input: "$data",
initialValue: {
$arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
},
in: {
$let: {
vars: {
currentr: "$$this", // Current processing element
currenta: "$$value" // Current accumulated value
},
in: {
$cond: [{ // Conditional expression to return the accumulated value as initial value for first element
$eq: ["$$currentr", "$$currenta"]
},
"$$currenta",
{ // From second element onwards prepare the cartesian product
$reduce: {
input: {
$map: {
input: "$$currenta",
as: a"a",
in: {
$map: {
input: "$$currentr",
as: r"r",
in: {
$mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
}
}
}
}
},
initialValue: [],
in: {
$concatArrays: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
}
}
}]
}
}
}
}
}
}
});
एकत्रीकरण($setUnion
. का उपयोग करके )।
यह समाधान केवल अधिक पठनीय पाइपलाइन देने के लिए सशर्त अभिव्यक्ति को दबाने के लिए जोड़ा गया था।
aggregate({
$project: {
cp: {
$reduce: {
input: "$data",
initialValue: {
$arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
},
in: {
$let: {
vars: {
currentr: "$$this", // Current processing element
currenta: "$$value" // Current accumulated value
},
in:{
$reduce: {
input: {
$map: {
input: "$$currenta",
as: "a",
in: {
$map: {
input: "$$currentr",
as: "r",
in: {
$mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
}
}
}
}
},
initialValue: [],
in: {
$setUnion: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
}
}
}
}
}
}
}
}
});
अपडेट करें
उपरोक्त दोनों समाधान सरणियों में दोहराए गए मानों के साथ काम नहीं करेंगे, जैसा कि नीचे दिए गए गलत $cond
के कारण Asya Kamsky की टिप्पणियों द्वारा नोट किया गया है पहले समाधान में और $setUnion
दूसरे समाधान में।
सही समाधान है
initialValue
with से शुरू करें का [ { } ]
या
input
बदलें input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},
जैसे पहले एलिमेंट को बाहर करने के लिए
पूर्ण एकत्रीकरण पाइपलाइन
aggregate({
$project: {
cp: {
$reduce: {
input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},
initialValue: {$arrayElemAt:["$data",0]},
in: {
$let: {
vars: {
currentr: "$$this",
currenta: "$$value"
},
in:{
$reduce: {
input: {
$map: {
input: "$$currenta",
as: "a",
in: {
$map: {
input: "$$currentr",
as: "r",
in: {
$mergeObjects: ["$$a", "$$r"]
}
}
}
}
},
initialValue: [],
in: {
$concatArrays: ["$$value", "$$this"]
}
}
}
}
}
}
}
}
});
संदर्भ:जावास्क्रिप्ट में अनेक सरणियों का कार्टेशियन उत्पादए>