2017-10-11 23 views
5

मैं दो संग्रहों में शामिल होने के लिए एक मैंगोडब एकत्रीकरण क्वेरी का उपयोग करने की कोशिश कर रहा हूं और फिर शामिल सरणी में सभी अद्वितीय मानों को अलग-अलग मानता हूं। * नोट: मुझे जरूरी नहीं है कि मेटाडेटा मैप में फ़ील्ड (कुंजी) क्या हैं। और मैं उन क्षेत्रों को गिनना या शामिल नहीं करना चाहता हूं जो मानचित्र में मौजूद हो या न हो। इसलिए यही कारण है कि समेकन क्वेरी ऐसा लगता है।मोंगोड एकत्रीकरण पाइपलाइन आकार और गति समस्या

तो मेरी दो संग्रह इस तरह दिखेगा: घटनाओं

{ 
"_id" : "1", 
"name" : "event1", 
"objectsIds" : [ "1", "2", "3" ], 
} 

ऑब्जेक्ट्स

{ 
"_id" : "1", 
"name" : "object1", 
"metaDataMap" : { 
        "SOURCE" : ["ABC", "DEF"], 
        "DESTINATION" : ["XYZ", "PDQ"], 
        "TYPE" : [] 
       } 
}, 
{ 
"_id" : "2", 
"name" : "object2", 
"metaDataMap" : { 
        "SOURCE" : ["RST", "LNE"], 
        "TYPE" : ["text"] 
       } 
}, 
{ 
"_id" : "3", 
"name" : "object3", 
"metaDataMap" : { 
        "SOURCE" : ["NOP"], 
        "DESTINATION" : ["PHI", "NYC"], 
        "TYPE" : ["video"] 
       } 
} 

मेरे परिणाम

{ 
_id:"SOURCE", count:5 
_id:"DESTINATION", count: 4 
_id:"TYPE", count: 2 
} 

हैं क्या मैं अब तक है यह है:

db.events.aggregate([ 
{$match: {"_id" : id}} 

,{$lookup: {"from" : "objects", 
     "localField" : "objectsIds", 
     "foreignField" : "_id", 
     "as" : "objectResults"}} 

,{$unwind: "$objectResults"} //Line 1 
,{$project: {x: "$objectResults.metaDataMap"}} //Line 2 


,{$unwind: "$x"} 
,{$project: {"_id":0}} 

,{$project: {x: {$objectToArray: "$x"}}} 
,{$unwind: "$x"} 

,{$group: {_id: "$x.k", tmp: {$push: "$x.v"}}} 

,{$addFields: {tmp: {$reduce:{ 
input: "$tmp", 
initialValue:[], 
in:{$concatArrays: [ "$$value", "$$this"]} 
    }} 
}} 

,{$unwind: "$tmp"} 
,{$group: {_id: "$_id", uniqueVals: {$addToSet: "$tmp"}}} 

,{$addFields: {count: {"$size":"$uniqueVals"}}} 
,{$project: {_id: "$_id", count: "$count"}} 
]); 

मेरी समस्या यह है कि मैंने लाइन 1 & 2 चिह्नित किया है। उपर्युक्त काम मेटाडेटा मैप फ़ील्ड (ऑब्जेक्ट्स रीसेट्स.मेटाडाटामैप) में 25,000 मानों के लिए लगभग 50 सेकंड लेते हैं। तो उदाहरण के लिए ऑब्जेक्ट 1 मेटाडेटामैप SOURCE सरणी में 25,000 मान हैं। धीमा करने का यही तरीका है। मेरे अन्य तेजी से यह करने के लिए जिस तरह से साथ लाइन 1 & 2 को बदलने के लिए किया गया था:

,{$project: {x: "$objectResults.metaDataMap"}} //Line 1 
,{$unwind: "$x"} //Line 2 

इस तरह तेजी से होता है (3 सेकंड से कम), लेकिन केवल डेटासेट है ~ 10000 आइटम या उससे कम पर चलाया जा सकता। कुछ भी अधिक है और मुझे यह कहते हुए एक त्रुटि मिलती है कि "अधिकतम दस्तावेज़ आकार से अधिक है"।

कृपया मदद करें!

+0

"विभिन्न सरणी में 25,000 आइटम" के आसपास थोड़ा और विवरण जोड़ सकता है? –

+1

बस एक विचार। हो सकता है कि आप अपनी 'मेटाडेटामैप' संरचना को 'मेटाडेटा मैप' में बदलने का प्रयास कर सकें: ["के": {"स्रोत", "वी": ["एबीसी", "डीईएफ"]} ...] 'और ' '$ लुकअप' के बाद $ map' चरण। '{" $ प्रोजेक्ट "की तरह कुछ: {" डेटा ": {" $ map ": {" इनपुट ":" $ objectResults.metaDataMap "," as ":" resultom "," in ": {" $ map ": {"इनपुट": "$$ परिणाम", "जैसा": "परिणाम", "इन": {"के": "$$ resultim.k", "v": {\t "$ आकार": \t "$ $ resultim.v "}}}}}}}}'। मेरा मानना ​​है कि इस तरह आप आकार प्राप्त कर सकते हैं और अवांछित जल्दी होना चाहिए। – Veeram

+0

लेकिन मुझे आकार के साथ एक अलग गिनती नहीं मिलेगी। क्या मैं मुझे वी मानों को कम करने की जरूरत है। – Deckard

उत्तर

0

आप object संग्रह पर अपने स्कीमा डिजाइन बदलने के लिए एक parent_id क्षेत्र शामिल करने के लिए सक्षम हैं, तो आप तुरंत अपने पाइप लाइन के पहले 4 चरणों (पहले $match, $lookup, $unwind, और $project) निकाल सकते हैं। यह Line 1 और Line 2 गायब होने की चिंता करेगा।

{ 
    "_id": "1", 
    "name": "object1", 
    "metaDataMap": { 
    "SOURCE": [ 
     "ABC", 
     "DEF" 
    ], 
    "DESTINATION": [ 
     "XYZ", 
     "PDQ" 
    ], 
    "TYPE": [ ] 
    }, 
    "parent_id": "1" 
} 

इस प्रकार आप महंगा $lookup और $unwind की जरूरत नहीं है:

उदाहरण के लिए, object संग्रह में कोई दस्तावेज़ कैसा दिखेगा। पहले 4 चरणों तो साथ बदला जा सकता:

db.objects.aggregate([ 
    {$match: {parent_id: id}} 
    ,{$project: {metaDataMap: {$filter: {input: {$objectToArray: '$metaDataMap'}, cond: {$ne: [[], '$$this.v']}}}}} 
    ,{$unwind: '$metaDataMap'} 
    ,{$unwind: '$metaDataMap.v'} 
    ,{$group: {_id: '$metaDataMap.k', val: {$addToSet: '$metaDataMap.v'}}} 
    ,{$project: {count: {$size: '$val'}}} 
]) 

हो जाएगा ताकि उत्पादन:

{ "_id": "TYPE", "count": 2 } 
{ "_id": "DESTINATION", "count": 4 } 
{ "_id": "SOURCE", "count": 5 } 

{$match: {parent_id: id}} 

इस विचार के आधार पर, मैं पाइप लाइन है, जो के परिणामस्वरूप के आगे अनुकूलन किया

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