नहीं, आप कॉल नहीं कर सकते .populate()
.aggregate()
. से पहले , और एक बहुत अच्छा कारण है कि आप क्यों नहीं कर सकते। लेकिन आप अलग-अलग तरीके अपना सकते हैं।
.populate()
विधि "क्लाइंट साइड" काम करती है जहां अंतर्निहित कोड वास्तव में अतिरिक्त क्वेरी करता है (या अधिक सटीक रूप से एक $in
query ) संदर्भित संग्रह से निर्दिष्ट तत्वों को "लुकअप" करने के लिए।
इसके विपरीत .aggregate()
एक "सर्वर साइड" ऑपरेशन है, इसलिए आप मूल रूप से "क्लाइंट साइड" सामग्री में हेरफेर नहीं कर सकते हैं, और फिर उस डेटा को बाद में एकत्रीकरण पाइपलाइन चरणों में उपलब्ध करा सकते हैं। यह सब उस संग्रह में मौजूद होना चाहिए जिस पर आप काम कर रहे हैं।
यहां एक बेहतर तरीका MongoDB 3.2 और बाद के संस्करण के साथ उपलब्ध है, $लुकअप
एकत्रीकरण पाइपलाइन संचालन। उपयोगकर्ता
. से संभालना भी शायद सबसे अच्छा है चयन को कम करने के लिए इस मामले में संग्रह:
User.aggregate(
[
// Filter first
{ "$match": {
"age": { "$gt": 20 }
}},
// Then join
{ "$lookup": {
"from": "scores",
"localField": "userID",
"foriegnField": "userID",
"as": "score"
}},
// More stages
],
function(err,results) {
}
)
यह मूल रूप से उपयोगकर्ता
. के भीतर एक नया क्षेत्र "स्कोर" शामिल करने जा रहा है अन्य संग्रह के लिए "लुकअप" से मेल खाने वाली वस्तुओं की "सरणी" के रूप में वस्तु:
{
"userID": "abc",
"age": 21,
"score": [{
"userID": "abc",
"score": 42,
// other fields
}]
}
नतीजा हमेशा एक सरणी होता है, क्योंकि सामान्य अपेक्षित उपयोग संभावित "एक से कई" संबंधों का "बाएं शामिल" होता है। यदि कोई परिणाम मेल नहीं खाता है तो यह केवल एक खाली सरणी है।
सामग्री का उपयोग करने के लिए, बस किसी भी तरह से एक सरणी के साथ काम करें। उदाहरण के लिए, आप $arrayElemAt
का उपयोग कर सकते हैं
किसी भी भविष्य के संचालन में सरणी का केवल पहला पहला तत्व प्राप्त करने के लिए ऑपरेटर। और फिर आप किसी भी सामान्य एम्बेडेड फ़ील्ड की तरह सामग्री का उपयोग कर सकते हैं:
{ "$project": {
"userID": 1,
"age": 1,
"score": { "$arrayElemAt": [ "$score", 0 ] }
}}
यदि आपके पास MongoDB 3.2 उपलब्ध नहीं है, तो किसी अन्य संग्रह के संबंधों द्वारा सीमित क्वेरी को संसाधित करने का आपका दूसरा विकल्प पहले उस संग्रह से परिणाम प्राप्त करना है और फिर $in
दूसरे पर फ़िल्टर करने के लिए:
// Match the user collection
User.find({ "age": { "$gt": 20 } },function(err,users) {
// Get id list
userList = users.map(function(user) {
return user.userID;
});
Score.aggregate(
[
// use the id list to select items
{ "$match": {
"userId": { "$in": userList }
}},
// more stages
],
function(err,results) {
}
);
});
इसलिए क्लाइंट को दूसरे संग्रह से मान्य उपयोगकर्ताओं की सूची प्राप्त करना और फिर उसे एक क्वेरी में दूसरे संग्रह में फीड करना पहले के रिलीज़ में ऐसा करने का एकमात्र तरीका है।