如何在MongoDB(MongoEngine)中执行此简单查询?

问题描述:

如何在_id = 4ef1fddbb33c45091d000000部分中使用ID = 1的主题获取所有消息?如何在MongoDB(MongoEngine)中执行此简单查询?

我有一些模型:

class Message(EmbeddedDocument): 
    id = SequenceField(unique=True) 
    content = StringField() 
    create_date = DateTimeField() 
    user = StringField() 
    active = BooleanField() 

class Theme(EmbeddedDocument): 
    id = SequenceField(unique=True) 
    title = StringField() 
    content = StringField() 
    create_date = DateTimeField() 
    user = StringField() 
    messages = ListField(EmbeddedDocumentField(Message)) 
    active = BooleanField() 

class Section(Document): 
    title = StringField(unique=True) 
    description = StringField() 
    themes = ListField(EmbeddedDocumentField(Theme)) 

而这一模式产生一些JSON,像这样:

{ 
    "_cls": "Section", 
    "_id": { 
     "$oid": "4ef1fddbb33c45091d000000" 
    }, 
    "_types": [ 
     "Section" 
    ], 
    "description": "Test description", 
    "themes": [ 
     { 
      "_types": [ 
       "Theme" 
      ], 
      "title": "Test", 
      "messages": [ 
       { 
        "content": "I'm content!", 
        "_types": [ 
         "Message" 
        ], 
        "id": 12, 
        "_cls": "Message" 
       }, 
       { 
        "content": "I'm second message!", 
        "_types": [ 
         "Message" 
        ], 
        "_cls": "Message", 
        "user": "inlanger", 
        "id": 13 
       } 
      ], 
      "content": "Test description", 
      "_cls": "Theme", 
      "id": 1 
     }, 
     { 
      "_types": [ 
       "Theme" 
      ], 
      "title": "Test2", 
      "messages": [ 
       { 
        "_types": [ 
         "Message" 
        ], 
        "create_date": { 
         "$date": "2012-01-31T11:29:17.120Z" 
        }, 
        "content": "Some message", 
        "_cls": "Message", 
        "id": 14, 
        "user": "inlanger" 
       } 
      ], 
      "content": "Test description 2", 
      "_cls": "Theme", 
      "id": 2 
     }, 
     { 
      "_types": [ 
       "Theme" 
      ], 
      "create_date": { 
       "$date": "2012-01-31T12:00:50.889Z" 
      }, 
      "title": "Ататата", 
      "messages": [], 
      "content": "Theme number 3", 
      "user": "inlanger", 
      "id": 15, 
      "_cls": "Theme" 
     } 
    ], 
    "title": "Test" 
} 

我使用一些代码...它工作的,但它的丑陋:

def get_theme_messages(section_id, theme_id, page = 1): 
    section = Section.objects(id = section_id, themes__id = theme_id).first() 
    for theme in section.themes: 
     if theme.id == int(theme_id): 
      return theme.messages 
      break 
     else: 
      pass 

MongoDB始终返回完整文档(即,使用Mongoengine说法的Document实例)。如果要在Document的列表中过滤EmbeddedDocument的列表,您必须在客户端代码中执行此操作(如此处所示)。

您可以通过删除一些不必要的线条有点收拾这个代码:

def get_theme_messages(section_id, theme_id, page = 1): 
    section = Section.objects(id = section_id, themes__id = theme_id).first() 
    for theme in section.themes: 
     if theme.id == int(theme_id): 
      return theme.messages 

(这在功能上等同于你在上面粘贴的)

+0

+1你可以限制你到达*域从文档返回(即仅检索消息),但在这种情况下这没有多大帮助。编辑:没关系,我发现那不是*的领域。 – 2012-01-31 18:11:47

+0

如果我有成千上万的记录这一切都正常吗? – inlanger 2012-01-31 18:14:48

+0

如果你有成千上万的'EmbeddedDocument',是的。如果您返回的是比您最终需要的更多*“文档”,则可以随时过滤查询。 – dcrosta 2012-01-31 19:33:41