2017-07-07 14 views
6

मेरा एप्लिकेशन एक ही बाल्टी में कई दस्तावेज़ प्रकार संग्रहीत कर रहा है। मुझे पता है कि यह अच्छा अभ्यास नहीं है लेकिन मेरे पास एक सीमा है कि मैं अपने सर्वर पर कितनी बाल्टी बना सकता हूं और इस समय इसके आसपास कोई रास्ता नहीं है। दस्तावेजों को उनके प्रकार से प्रीफ़िक्स्ड किया जाता है, इसलिए जब मुझे कोई दस्तावेज़ मिलता है तो मुझे कुंजी प्राप्त करने के लिए उपसर्ग और आईडी को संयोजित करने की आवश्यकता होती है और मैं एक कुंजी लुकअप कर सकता हूं।नक्शा के साथ कोचबेस में डेटा कैसे मर्ज करें?

मुझे एक ऐसी रिपोर्ट बनाने की आवश्यकता है जो एक से अधिक दस्तावेज़ प्रकारों से जानकारी प्रदान करे।

मेरे मानचित्र इस तरह दिखता है:

"total_rows":...,"rows":[ 
{"id":"DC_1","key":1,"value":{"hotelId":1,"exit":3,"email":"t[email protected]","contact":"Jeno"}}, 
{"id":"HDESC_1","key":1,"value":{"hotelId":1,"exit":3,"description":".","hotelRoomTypeId":0,"starRating":5}}, 
{"id":"LOC_1","key":1,"value":{"hotelId":1,"exit":2,"city":"Barcelona","zip":"1222","country":"Spain","street":"Catalonia, someplacenice"}}, 
{"id":"PRP_1","key":1,"value":{"hotelId":1,"exit":1}}, 
{"id":"PRP_2","key":2,"value":{"hotelId":2,"exit":1}}, 
{"id":"AM_3","key":3,"value":{"hotelId":3,"exit":4}}, 
{"id":"AM_4","key":4,"value":{"hotelId":4,"exit":4}}, 
{"id":"PHOTOS_4","key":4,"value":{"hotelId":4,"exit":7}}, 
{"id":"PRP_4","key":4,"value":{"hotelId":4"exit":1}}, 
{"id":"AM_4","key":4,"value":{"hotelId":4,"exit":4}}, 
{"id":"PRP_4","key":4,"value":{"hotelId":4,"exit":1}}, 
{"id":"PHOTOS_5","key":5,"value":{"hotelId":5,"exit":7}} 
... 

] 

मैं समूह के लिए hotelId से तारीख, जिस नई कुंजी है कोशिश कर रहा हूँ और एक दस्तावेज़ में फ़ील्ड विलय:

function(doc, meta) { 

    var getStep = function(stepName, exit, mapper) { 
    if (meta.id.indexOf(stepName) !== -1) { 
     var hotelId = parseInt(meta.id.replace(stepName + '_', '')); 
     if (hotelId > 0) { 
     var result = { 
      hotelId: hotelId, 
      exit: exit 
     }; 
     if (mapper !== undefined) { 
      mapper(result); 
     } 
     return result; 
     } 
    } 
    return null; 
    }; 

    var photos = getStep('PHOTOS', 7); 
    if (photos != null) { 
    emit(photos.hotelId, photos); 
    } 
    var pricing = getStep('PICR', 5); 
    if (pricing != null) { 
    emit(pricing.hotelId, pricing); 
    } 
    var owner = getStep('OWNER', 1); 
    if (owner != null) { 
    emit(owner.hotelId, owner); 
    } 
    var amenity = getStep('AM', 4); 
    if (amenity != null) { 
    emit(amenity.hotelId, amenity); 
    } 
    var description = getStep('HDESC', 3, function(result) { 
    result.description = doc.description; 
    result.hotelRoomTypeId = doc.hotelRoomTypeId; 
    result.starRating = doc.starRating; 
    }); 
    if (description != null) { 
    emit(description.hotelId, description); 
    } 
    var contact = getStep('DC', 3, function(result) { 
    result.email = doc.emailAddress; 
    result.contact = doc.mainContactName; 
    }); 
    if (contact != null) { 
    emit(contact.hotelId, contact); 
    } 
    var location = getStep('LOC', 2, function(result) { 
    result.city = doc.cityName; 
    result.zip = doc.postalCode; 
    result.country = doc.countryName; 
    result.street = doc.stateName + ', ' + doc.streetName; 
    }); 
    if (location != null) { 
    emit(location.hotelId, location); 
    } 
    var property = getStep('PRP', 1, function(result) { 
    result.paymentMethodId = doc.paymentMethodId 
    }); 
    if (property != null) { 
    emit(property.hotelId, property); 
    } 
} 

यह इस उत्पादन उत्पन्न करता है एक कस्टम reducer के साथ। मुझे त्रुटि प्रकार के आधार पर अलग-अलग त्रुटियां मिल रही हैं लेकिन सभी त्रुटियों से संकेत मिलता है कि रेड्यूसर कितनी तारीख लौट सकता है इस पर एक सीमा है। यदि मैं किसी ऑब्जेक्ट से रिटर्न प्रकार को एक एसोसिएटिव सरणी में बदलता हूं जो बहुत अधिक काम करता है तो मुझे एक बेहतर त्रुटि मिलती है।

function(key, values, rereduce) { 
    if (rereduce) { 
    return values; 
    } else { 
    var results = {}; // Object! 
    for (var i = 0; i < values.length; i++) { 
     var row = values[i]; 
     if (!results[row.hotelId]) { 
     results[row.hotelId] = { 
      phone: '', 
      exit: 1 
     }; 
     } 
     var result = results[row.hotelId]; 
     for (var name in row) { 
     result[name] = row[name]; 
     } 
     if (row.exit > row.exit) { 
     result.exit = row.exit; 
     } 
    }; 

    return results; 
    } 
} 

मुझे देता है RangeError: Maximum call stack size exceeded

function(key, values, rereduce) { 
    if (rereduce) { 
    return values; 
    } else { 
    var results = []; // Array! 
    for (var i = 0; i < values.length; i++) { 
     var row = values[i]; 
     if (!results[row.hotelId]) { 
     results[row.hotelId] = { 
      phone: '', 
      exit: 1 
     }; 
     } 
     var result = results[row.hotelId]; 
     for (var name in row) { 
     result[name] = row[name]; 
     } 
     if (row.exit > row.exit) { 
     result.exit = row.exit; 
     } 
    }; 

    return results; 
    } 
} 

मुझे देता है reduction too large error

function(key, values, rereduce) { 
    if (rereduce) { 
    return values; 
    } else {  
    return values; 
    } 
} 

मुझे RangeError: Maximum call stack size exceeded

देता है अगर मैं चलाएँ:

function(key, values, rereduce) { 
    if (rereduce) { 
    return values; 
    } else {   
    return values.length; 
    } 
} 

मैं वापस पाने:

[ 68, 72, 65, 66, 68, 68, 70, 114 ] 

JavaScript इंजन अधिकतम 114 आकार और आउटपुट डेटा के साथ सरणियों कम करने के लिए भी छोटा होना चाहिए सक्षम होना चाहिए। स्पष्ट रूप से इस बात पर एक सीमा है कि कितना डेटा कम हो सकता है max_kv_size_per_doc जो 1 एमबी भी है 10 सेकंड निष्पादन सीमा है लेकिन मेरे मामले में यह कुछ और है। क्या एल्गोरिदम बदलकर, सरणी या सरणी या कुछ बदलकर इन सीमाओं को पार करने का कोई तरीका है? क्या मैप में कुछ ऐसा कर सकता है या कुछ चाल जो मैं पुनरुत्थान में उपयोग कर सकता हूं?

+0

एक) एकाधिक दस्तावेज़ प्रकार के होने एक बाल्टी में एक बुरा व्यवहार नहीं है, यह बहुत आम है, और अक्सर अनुशंसित। –

+0

बी) आप कोचबेस का किस संस्करण का उपयोग कर रहे हैं? क्या N1QL आपके लिए कोई विकल्प नहीं है? –

+0

सी) "अधिकतम कॉल स्टैक आकार पार हो गया" एक जावास्क्रिप्ट त्रुटि की तरह लगता है; आदर्श रूप से आप इसके माध्यम से डीबग कर सकते हैं और पता लगा सकते हैं कि यह कहां से आ रहा है, लेकिन यह सुनिश्चित नहीं है कि –

उत्तर

3

मैंने इसे समझ लिया। यह काम करता है अगर मैं यौगिक कुंजी और group_level का उपयोग करें।

तो अगर मैं अपने नक्शा बदल होटल आईडी के लिए कुंजी के रूप में एक सरणी वापस जाने के लिए और मैं सेट group_level = 1 तो मानों मेरे लिए समूहीकृत किया जाएगा जैसा कि मैंने शुरू में उम्मीद:

function(doc, meta) { 

    var getStep = function(stepName, exit, mapper) { 
    if (meta.id.indexOf(stepName) !== -1) { 
     var hotelId = parseInt(meta.id.replace(stepName + '_', '')); 
     if (hotelId > 0) { 
     var result = { 
      hotelId: hotelId, 
      exit: exit 
     }; 
     if (mapper !== undefined) { 
      mapper(result); 
     } 
     return result; 
     } 
    } 
    return null; 
    }; 

    var photos = getStep('PHOTOS', 7); 
    if (photos != null) { 
    emit([photos.hotelId], photos); // array as key 
    } 
    var pricing = getStep('PICR', 5); // array as key 
    if (pricing != null) { 
    emit([pricing.hotelId], pricing); 
    } 
    var owner = getStep('OWNER', 1); // array as key 
    if (owner != null) { 
    emit([owner.hotelId], owner); 
    } 
    var amenity = getStep('AM', 4); // array as key 
    if (amenity != null) { 
    emit([amenity.hotelId], amenity); 
    } 
    var description = getStep('HDESC', 3, function(result) { 
    result.description = doc.description; 
    result.hotelRoomTypeId = doc.hotelRoomTypeId; 
    result.starRating = doc.starRating; 
    }); 
    if (description != null) { 
    emit([description.hotelId], description); // array as key 
    } 
    var contact = getStep('DC', 3, function(result) { 
    result.email = doc.emailAddress; 
    result.contact = doc.mainContactName; 
    }); 
    if (contact != null) { 
    emit([contact.hotelId], contact); // array as key 
    } 
    var location = getStep('LOC', 2, function(result) { 
    result.city = doc.cityName; 
    result.zip = doc.postalCode; 
    result.country = doc.countryName; 
    result.street = doc.stateName + ', ' + doc.streetName; 
    }); 
    if (location != null) { 
    emit([location.hotelId], location); // array as key 
    } 
    var property = getStep('PRP', 1, function(result) { 
    result.paymentMethodId = doc.paymentMethodId 
    }); 
    if (property != null) { 
    emit([property.hotelId], property); // array as key 
    } 
} 

तब मैं स्थापित करने की आवश्यकता group_level=1 और reduce=true। आप इसे दृश्य संपादक या क्वेरी स्ट्रिंग में कर सकते हैं।

पिछले सा है को कम:

function(key, values, rereduce) { 
    if (rereduce) { 
    return values; 
    } else {   
    var result = {}; 
    values.forEach(function(item){ 
     for(var name in item){ 
      result[name] = item[name]; 
     } 
    }); 

    return result; 
    } 
} 

परिणाम hotelId द्वारा विलय हो जाएगा के रूप में उम्मीद :)

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