2012-09-12 13 views
9

में एम्बेडेड दस्तावेज़ों की एक सूची अपडेट करना मैं mongoengine वाक्यविन्यास के साथ संघर्ष कर रहा हूं।mongoengine

मैं निम्नलिखित मॉडल ...

class Post(EmbeddedDocument): 
    uid = StringField(required=True) 
    text = StringField(required=True) 
    when = DateTimeField(required=True) 


class Feed(Document): 
    label = StringField(required=True) 
    feed_url = StringField(required=True) 
    posts = ListField(EmbeddedDocumentField(Post)) 

    def my_method(self, post): 
     pass 

... और बाद वस्तु में पारित कर दिया साथ my_method, मैं किसी मौजूदा पोस्ट अपडेट करना चाहते हैं अगर यह एक साथ self.posts में मौजूद है यूआईडी से मिलान करना, या अगर नहीं तो self.posts को दबाएं।

क्या मोंगोएन्गिन में एक कॉल में ऐसा करने के लिए वाक्यविन्यास है?

उत्तर

15

सूची फ़ील्ड के साथ आप एक ही क्वेरी में किसी सूची में अपरिवर्तित नहीं कर सकते हैं। $addToSet काम नहीं करेगा क्योंकि आपने post बदल दिया है ताकि आप मिलान नहीं कर सकें। आप इस दौर कोड कर सकते हैं लेकिन यह एक रेस स्थिति जहां त्रुटि उदाहरण के लिए अवसर की एक छोटी सी खिड़की है पैदा करता है:

class Post(EmbeddedDocument): 
     uid = StringField(required=True) 
     text = StringField(required=True) 

    class Feed(Document): 
     label = StringField(required=True) 
     feed_url = StringField(required=True) 
     posts = ListField(EmbeddedDocumentField(Post)) 

    Feed.drop_collection() 

    Feed(
     label="label", 
     feed_url="www.feed.com" 
    ).save() 

    post = Post(uid='1', text="hi") 
    updated = Feed.objects(posts__uid=post.uid).update_one(set__posts__S=post) 
    if not updated: 
     Feed.objects.update_one(push__posts=post) 

पहले हम अद्यतन करने के लिए कोशिश करते हैं और अगर यह मौजूद नहीं है हम सूची में धक्का - यह वह जगह है जहां दूसरी प्रक्रिया चलाने के अवसर की एक खिड़की है और सूची में post को संभावित रूप से धक्का दे रहा है।

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

+0

बिल्कुल सही, धन्यवाद! –

+0

@Ross इस प्रतिक्रिया को कैसे प्राप्त करें 'WriteResult ({"nMatched": 0, "nupserted": 0, "nmodified": 0})' mongoengine' का उपयोग करके? मैं यह जांचना चाहता हूं कि आइटम मिला था या नहीं। धन्यवाद –

0
Feed.objects.filter(posts__uid=post.uid).\ 
      update_one(push__posts__S__comments='comment demo') 
संबंधित मुद्दे