2010-12-05 16 views
8

मेरे पास lists संग्रह है जहां प्रत्येक दस्तावेज़ में members की सरणी है। members सरणी का प्रत्येक तत्व email संपत्ति, date संपत्ति, और कुछ अन्य मेटा के साथ एक दस्तावेज़ है। मेरे पास एक ही सूची में दो बार एक ही ईमेल में प्रवेश करने से रोकने के लिए members.email पर एक अनन्य अनुक्रमणिका है, लेकिन मैं मूल date मान को बनाए रखना चाहता हूं। दुर्भाग्यवश, न तो $addToSet और न ही $push ऐसा प्रतीत होता है।

$ धक्का का उपयोग कर उदाहरण:

$lists->update(array('_id' => $list['_id'], 'members.email' => array('$ne' => $email)), array('$push' => array('members' => array(
    'email' => $email, 
    'date' => new MongoDate(), 
    // etc. 
)))); 

और $ addToSet साथ:

$lists->update(array('_id' => $list['_id']), array('$addToSet' => array('members' => array(
    'email' => $email, 
    'date' => new MongoDate(), 
    // etc. 
)))); 

दोनों उदाहरण पूरे एम्बेडेड दस्तावेज़ नए के साथ की वजह से (मुझे लगता है) अद्वितीय date मूल्य बदलें। क्या $push "सदस्य" दस्तावेज़ संभव है यदि members.email पहले से मौजूद नहीं है या मुझे इसे दो आदेशों में करने की आवश्यकता होगी?

वैकल्पिक रूप से, members को अपने संग्रह में parent_list-संपत्ति के साथ रखने के लिए बेहतर स्केलेबिलिटी-वार होगा?

उत्तर

1

संग्रह क्यों नहीं है जहां आप list_id, ईमेल, add_date स्टोर करते हैं, फिर आप 2 कुंजी list_id और ईमेल पर एक अनन्य अनुक्रमणिका बनायेंगे। इससे प्रविष्टि एक ही सूची_आईडी के साथ रिकॉर्ड के

एम्बेडेड दस्तावेज़ नहीं होंगे। आप अभी भी list_id

0

द्वारा ढूंढें() का उपयोग कर सकते हैं हां यह संभव है। MongoDB advanced queries अनुभाग में $ मौजूद ऑपरेटर देखें। जब सदस्य ईमेल मौजूद नहीं होता है तो केवल उस अद्यतन के लिए एक कथन में एक $ मौजूद स्थिति को कोड करें।

+1

मैं लगभग सकारात्मक $ मौजूद समाधान मैं तलाश कर रहा हूँ नहीं है। – Kevin

5

मेरे अनुभव में आप "$ push" या "$ addToSet" नहीं कर सकते हैं क्योंकि आपका लक्ष्य "सदस्य" शायद एक एम्बेडेड ऑब्जेक्ट है (या इसके निर्माण के बाद एक में परिवर्तित किया गया है)। आप एम्बेडेड सरणी पर केवल $ पुश, $ pushAll, $ addToSet का उपयोग कर सकते हैं ...

दुर्भाग्यवश हमारे लिए php डेवलपर्स एक कर्सर क्वेरी हमेशा डेटा को सरणी के रूप में वापस लौटाता है, यह देखने के लिए सबसे अच्छा तरीका है कि "सदस्य" एक सरणी या वस्तु है, मोंगो खोल में एक खोज() चलाने के लिए है और परिणाम में घुंघराले/वर्ग ब्रैकेट ("{}" या "[]") के लिए देखो।

उम्मीद है कि इससे मदद मिलती है।

0

IIUC, एम्बेडेड दस्तावेज़ (यदि ऐसा है) को अपडेट करने के लिए Upsert का उपयोग करने का प्रयास करें या इसे डालें (यदि कोई नहीं है)। this भी देखें।

स्केलेबिलिटी के संबंध में आपसे दूसरे प्रश्न के रूप में, यह वास्तव में मामला निर्भर है ... माता-पिता में दस्तावेज़ को एम्बेड करने के लिए कठिन अपडेट और बड़े डेटा लाने की आवश्यकता होती है, लेकिन fetch क्वेरी गिनती को कम करता है। एक ही ईमेल के सदस्यों के साथ फ़िल्टर कर दस्तावेजों को क्वेरी condiction में

1

उपयोग $ne:

$lists->update(array('_id' => $list['_id'], 
        'members.email' => array('$ne' => $email)), 
       array('$addToSet' => array('members' => array(
        'email' => $email, 
        'date' => new MongoDate(), 
         // etc. 
)))); 
संबंधित मुद्दे

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