使用 Mongoengine 通过正则表达式匹配嵌入文档

Match embedded Documents by Regular expression with Mongoengine

我有一个文档列表,每个文档包含 50 个(这可能会有所不同)EmbeddedDocument。现在我想查询所有包含以特定模式开头的 id 的 EmbeddedDocument(跨所有文档)。

class Container(Document):
    list = EmbeddedDocumentListField(Data)

class Data(EmbeddedDocument):
    id=StringField(required=True, primary_key=True)

现在查询(或类似 startswith 的查询)将在数据的 'id' 上。

作为嵌入式字段,您需要使用 "double underscore" __ to denote the field as compared to native "dot notation" as well as the startswithistartswith 修饰符的嵌入式语法:

Container.objects(list__id__startswith="AAA")

否则,如果您需要 "real" 正则表达式而不是允许的快捷方式,则可以将 __raw__ 修饰符与 "raw" MongoDB 语法查询一起使用:

Container.objects(__raw__={ "list.id": ,re.compile('^AAA', re.IGNORECASE) })

或者可能 "list._id" 取决于字段名称是如何被告知为嵌入对象序列化的。

无论哪种方式,本质上都是将查询卸载到数据库,在那里它可以使用它的特性来确定匹配项。

当然有一个基本的 mongoengine 限制,即无法简单地投影匹配的数组元素。这就是关于如何读取和实例化 class 数据的全部内容。

您可以 return "raw python objects" 作为实施的 class 的替代方法,使用 .aggregate() 方法:

Container._get_collection().aggregate({
    { "$match": { "list.id": ,re.compile('^AAA', re.IGNORECASE) } },
    { "$unwind": "$list" },
    { "$match": { "list.id": ,re.compile('^AAA', re.IGNORECASE) } },
    { "$group": {
        "_id": "$_id",
        "list": { "$push": "$list" }
    }}
])

因此不再是相同的 class 定义,但也没有什么可以阻止您提供原始数据以在需要时实例化所需 class 的新对象。