使用 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 startswith
或 istartswith
修饰符的嵌入式语法:
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 的新对象。
我有一个文档列表,每个文档包含 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 startswith
或 istartswith
修饰符的嵌入式语法:
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 的新对象。