आप इसे "दो चरण" ऑपरेशन के रूप में एकत्रीकरण ढांचे के साथ कर सकते हैं। जो पहले आइटम को $push के ज़रिए एक ऐरे में जमा करना है
एक $group
के साथ
पाइपलाइन, और फिर उपयोग करने के लिए $concat
$reduce
के साथ
अंतिम प्रक्षेपण में उत्पादित सरणी पर:
db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
{ "$addFields": {
"client_id": {
"$reduce": {
"input": "$client_id",
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ "$$value", "" ] },
"then": "$$this",
"else": {
"$concat": ["$$value", ",", "$$this"]
}
}
}
}
}
}}
])
हम $cond
भी लागू करते हैं
परिणामों में अल्पविराम के साथ एक खाली स्ट्रिंग को जोड़ने से बचने के लिए, इसलिए यह एक सीमित सूची की तरह दिखता है।
FYI करें एक JIRA समस्या है SERVER-29339
जो $reduce
की मांग करता है
एक संचयक व्यंजक
के रूप में क्रियान्वित करने के लिए इसे सीधे $group
में इस्तेमाल करने की अनुमति देने के लिए
पाइपलाइन चरण। जल्द ही किसी भी समय होने की संभावना नहीं है, लेकिन सैद्धांतिक रूप से यह की जगह ले लेगा। $पुश
उपरोक्त में और ऑपरेशन को एकल पाइपलाइन चरण बनाएं। नमूना प्रस्तावित वाक्य रचना JIRA मुद्दे पर है।
अगर आपके पास $reduce
नहीं है
(MongoDB 3.4 की आवश्यकता है) तो बस कर्सर को पोस्ट करें:
db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
]).map( doc =>
Object.assign(
doc,
{ "client_id": doc.client_id.join(",") }
)
)
जो तब mapReduce
अगर आपको वास्तव में चाहिए:
db.collection.mapReduce(
function() {
emit(this.tag_id,this.client_id);
},
function(key,values) {
return [].concat.apply([],values.map(v => v.split(","))).join(",");
},
{ "out": { "inline": 1 } }
)
निश्चित रूप से कौन सा विशिष्ट mapReduce
. में आउटपुट करता है _id
. का रूप और मान
चाबियों के सेट के रूप में, लेकिन यह मूल रूप से आउटपुट है।
हम उपयोग करते हैं [].concat.apply([],values.map(...))
क्योंकि "reducer" का आउटपुट "सीमांकित स्ट्रिंग" हो सकता है क्योंकि mapReduce
बड़े परिणामों के साथ वृद्धिशील रूप से काम करता है और इसलिए रेड्यूसर का आउटपुट दूसरे पास पर "इनपुट" बन सकता है। इसलिए हमें उम्मीद करनी चाहिए कि ऐसा हो सकता है और उसी के अनुसार इसका इलाज करें।