2012-08-03 43 views
4

從四天,我正在試圖弄清楚如何遵循一個參考到另一個類,從中beeing引用的類開始。在SQL-的Django有一個related_name實現這個...的MongoDB - MongoEngine - 如何遵循「對方」的參考?

例如,我有這個類:

class MyClass(Document): 
    ... 
    other_classes = ListField(ReferenceField(Other_Class)) 

這一個:

class Other_Class(Document): 
    ... 

現在我想從Other_Class去到MyClass ...有什麼想法?

感謝,

羅恩

回答

3

下面是一個測試用例展示瞭如何查詢它:

import unittest 
from mongoengine import * 


class StackOverFlowTest(unittest.TestCase): 

    def setUp(self): 
     conn = connect(db='mongoenginetest') 

    def test_one_two_many(self): 

     class MyClass(Document): 
      other_classes = ListField(ReferenceField("OtherClass")) 

     class OtherClass(Document): 
      text = StringField() 

     MyClass.drop_collection() 
     OtherClass.drop_collection() 

     o1 = OtherClass(text='one').save() 
     o2 = OtherClass(text='two').save() 
     m = MyClass(other_classes=[o1, o2]).save() 

     # Lookup MyClass that has o1 in its other_classes 
     self.assertEqual(m, MyClass.objects.get(other_classes=o1)) 

     # Lookup MyClass where either o1 or o2 matches 
     self.assertEqual(m, MyClass.objects.get(other_classes__in=[o1, o2])) 

主要問題是你需要存儲在MyClass引用列表?這可能是更有效的關係,只存儲在OtherClass ..

0

一邊想着我的問題,我想出了一個解決方案。

我只是我引用類的ID添加到我的模型。

下面是一個例子:

class MyClass(Document): 
    ... 
    other_classes = ListField(ReferenceField(Other_Class)) 

class Other_Class(Document): 
    myclass = ReferenceField(MyClass) 

我不太清楚這是否是蒙戈-方式做到這一點,但我敢肯定它的工作原理:)

您也可以選擇忽略在MyClassother_classes屬性,以避免冗餘,但那麼你就需要這樣的查詢,以獲得「子」對象:

+0

這是可能的,但世界上沒有需要保持對關係的兩個引用。 – Ross 2012-08-03 09:18:49

0

嘗試此查詢:

oc = Other_Class() 
MyClass.objects.find(other_classes__all = [oc.id]) 
+0

不錯的主意......但是與我的「冗餘」解決方案相比,這個查詢是否有很好的性能? – Ron 2012-08-03 08:43:07

+2

@Ron您的解決方案確實具有更好的性能。但是,保持交叉引用同步可能有點困難。其實你能做的最好的事情是在'Other_Class'使用'ReferenceField'和'MyClass'刪除'other_classes'場。你不需要它,因爲無論如何你必須查詢'other_classes'。 – freakish 2012-08-03 08:45:48

+0

感謝您的回覆。但是如果我刪除'MyClass'中的'ListField',我怎樣才能從'MyClass'獲得'Other_Class'es?例如,如果我有一個線程和幾個職位。不時,我需要從一個帖子開始,並獲得父線程。但在大多數情況下,我只是從線程開始,需要我所有的帖子。那麼我怎樣才能刪除線程中的ListField呢? (是的,一個職位將是一個線程中嵌入的文件,但它只是一個例子;)) – Ron 2012-08-03 08:58:33