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

0 投票
1 回答
2217 浏览
提问于 2025-04-17 12:03

我想知道怎么从主题(Theme)中获取所有消息,这个主题的ID是1,而在一个特定的部分(Section)中,这个部分的ID是4ef1fddbb33c45091d000000。

我有一个模型:

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

1 个回答

3

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

(这和你上面粘贴的功能是一样的)

撰写回答