2016-10-07 11 views
7

दो सहकर्मियों, टैग और व्यक्तियों को मिला।

टैग मॉडल:

{ 
    en: String, 
    sv: String 
} 

व्यक्ति मॉडल:

{ 
    name: String, 
    projects: [ 
    title: String, 
    tags: [ 
     { 
     type: Schema.ObjectId, 
     ref: 'tag' 
     } 
    ] 
    ] 

} 

मैं क्वेरी जो सभी टैग व्यक्ति मॉडल में उपयोग में है कि रिटर्न चाहते हैं। सभी दस्तावेज़।

var query = mongoose.model('tag').find({...}); 

तरह Sometehing या मैं किसी भी तरह इस करने के लिए समेकित दृष्टिकोण इस्तेमाल करना चाहिए?

+0

आप किसी खास व्यक्ति के लिए पूरे आवेदन में सभी टैग या सभी टैग चाहते हैं: 3.0 जो $lookup ऑपरेटर के लिए समर्थन की जरूरत नहीं है के रूप में एकत्रीकरण से परिणाम को भरने के लिए है? क्योंकि यदि आप संबंधित टैग के बिना सभी टैग सूचीबद्ध करना चाहते हैं, तो आप टैग संग्रह पर सीधे पूछ सकते हैं। –

+0

मैं पूरे एप्लिकेशन में टैग चाहता हूं। सभी टैग के लिए project.tags में मौजूद सभी टैग। – Per

उत्तर

19

किसी विशेष व्यक्ति दस्तावेज़ के लिए, आप

var query = mongoose.model("person").find({ "name": "foo" }).populate("projects.tags"); 

तरह populate() समारोह का उपयोग कर सकते और अगर आप किसी भी व्यक्तियों उदाहरण के लिए 'MongoDB' या 'नोड जे एस' के साथ किसी भी कोड है तो खोज करना चाहते हैं, तो आप के रूप में populate() समारोह अधिभार में क्वेरी विकल्प शामिल कर सकते हैं:

var query = mongoose.model("person").find({ "name": "foo" }).populate({ 
    "path": "projects.tags", 
    "match": { "en": { "$in": ["MongoDB", "Node JS"] } } 
}); 

आप सभी टैग सभी लोगों के लिए "project.tags" में मौजूदा चाहते हैं, तो एकत्रीकरण ढांचा जाने का रास्ता है। व्यक्ति संग्रह पर इस पाइपलाइन चल रहा है और विचार करें टैग संग्रह पर शामिल होने के एक छोड़ दिया करने के लिए $lookup ऑपरेटर का उपयोग करता है:

mongoose.model('person').aggregate([ 
    { "$unwind": "$projects" }, 
    { "$unwind": "$projects.tags" }, 
    { 
     "$lookup": { 
      "from": "tags", 
      "localField": "projects.tags", 
      "foreignField": "_id", 
      "as": "resultingTagsArray" 
     } 
    }, 
    { "$unwind": "$resultingTagsArray" }, 
    { 
     "$group": { 
      "_id": null, 
      "allTags": { "$addToSet": "$resultingTagsArray" }, 
      "count": { "$sum": 1 } 
     } 
    } 
]).exec(function(err, results){ 
    console.log(results); 
}) 

किसी विशेष व्यक्ति के लिए तो पहला कदम फिल्टर करने के लिए के रूप में एक $match पाइपलाइन लागू दस्तावेज:

mongoose.model('person').aggregate([ 
    { "$match": { "name": "foo" } }, 
    { "$unwind": "$projects" }, 
    { "$unwind": "$projects.tags" }, 
    { 
     "$lookup": { 
      "from": "tags", 
      "localField": "projects.tags", 
      "foreignField": "_id", 
      "as": "resultingTagsArray" 
     } 
    }, 
    { "$unwind": "$resultingTagsArray" }, 
    { 
     "$group": { 
      "_id": null, 
      "allTags": { "$addToSet": "$resultingTagsArray" }, 
      "count": { "$sum": 1 } 
     } 
    } 
]).exec(function(err, results){ 
    console.log(results); 
}) 

एक और वैकल्पिक हल यदि आप MongoDB संस्करणों का उपयोग कर रहे हैं> = 2.6 या < =

mongoose.model('person').aggregate([ 
    { "$unwind": "$projects" }, 
    { "$unwind": "$projects.tags" },  
    { 
     "$group": { 
      "_id": null, 
      "allTags": { "$addToSet": "$projects.tags" } 
     } 
    } 
], function(err, result) { 
    mongoose.model('person') 
    .populate(result, { "path": "allTags" }, function(err, results) { 
     if (err) throw err; 
     console.log(JSON.stringify(results, undefined, 4)); 
    }); 
}); 
+0

क्षमा करें! मैंने अपनी पोस्ट में गलती की। परियोजनाएं एक वस्तु नहीं है। यह एक सरणी है। मैंने सवाल अपडेट कर लिया है। क्या आप फिर से देख सकते हैं? – Per

+0

आप अपडेट किए गए उत्तर में, किसी अन्य '{" $ unwind ":" $ projects "}' पाइपलाइन को उपसर्ग करके इसे ठीक कर सकते हैं। – chridam

+1

बहुत शक्तिशाली सामान। एक दिन इस समेकन ढांचे को सीखना होगा। धन्यवाद! – Per

1

यदि आप MongoDb संस्करण 3.2 का उपयोग कर रहे हैं तो आप $lookup का उपयोग कर सकते हैं जो बाएं बाहरी जुड़ने में काम करता है।

संबंधित मुद्दे