我将Mongoengine与Django结合使用。
我的模型中有一个嵌入式字段。这是嵌入式文档的列表字段。
import mongoengine
class OrderStatusLog(mongoengine.EmbeddedDocument):
status_code = mongoengine.StringField()
class Order(mongoengine.DynamicDocument):
incr_id = mongoengine.SequenceField()
status = mongoengine.ListField(mongoengine.EmbeddedDocumentField(OrderStatusLog))
现在,我想Order
根据status
字段中的最后一个值对收集结果进行过滤。
例如 Order.objects.filter(status__last__status_code="scode")
我猜没有这样的事__last
。我尝试了文档http://docs.mongoengine.org/guide/querying.html#querying-lists中提到的方法,但是没有用。
我可以通过遍历集合中的所有文档来解决此问题,但那不是很有效,我们如何才能有效地编写此查询。
我不确定MongoEngine是否可以做到这一点。AFAIK,您需要使用聚合管道。
在Mongo Shell中,使用'$ slice'和$arrayElemAt
运算符:
db.order.aggregate([{ $project: {last_status: { $arrayElemAt: [{ $slice: [ "$status", -1 ] }, 0 ]} }}, {$match: {'last_status.status_code':"scode"}} ])
在Python中:
pipeline = [
{'$project': {'last_status': { '$arrayElemAt': [{ '$slice': [ "$status", -1 ] }, 0 ]} }},
{'$match': {'last_status.status_code':'scode'}}
]
agg_cursor = Order.objects.aggregate(*pipeline)
result = [ Order.objects.get(id=order['_id']) for order in agg_cursor ]
这里的技巧是objects.aggregate
提供一个PyMongo
游标,而不是一个MongoEngine
游标,因此,如果需要MongoEngine
对象,则可以分两步进行:首先使用聚合框架进行过滤以获取匹配项的ID,然后通过MongoEngine
查询来获取它们。
这就是我的工作。根据我的测试,事实证明,它比获取所有内容并在python代码中过滤要有效得多。
如果有更简单的方法,我很想听听。否则,这可能是MongoEngine的功能请求。您可能要在那里开一个问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句