当将aggregate与mongoengine一起使用时,它返回一个CommandCursor而不是mongoengine对象列表,这意味着mongonengine并不真正被使用,
例如:如果某个文档没有标题字段,则会引发错误。如何将结果转换为mongoengine对象?
class Post(Document):
title = StringField(max_length=120, required=True)
author = ReferenceField(User)
Host.objects()
# [<Post: Post object>, <Post: Post object>, ...]
pipeline = [
{
"$match": {
'types': type,
}
},
{
"$project": {
"name": 1,
'brating': {
"$divide": [
{"$add": ["$total_score", 60]},
{"$add": ["$total_votes", 20]}
]
}
}
},
{"$sort": {"brating": -1}},
{"$limit": 100}
]
Host.objects.aggregate(*pipeline)
# <class 'pymongo.command_cursor.CommandCursor'>
list(Host.objects.aggregate(*pipeline))
# <class 'list'>发布于 2016-12-29 16:14:22
aggregate函数只是底层pymongo函数的快捷方式。
从aggregate返回的文档可能涉及一些$group或其他阶段,这意味着它们与对象模型无关,因此mongoengine无法将它们转换为mongoengine对象。
在管道的情况下,您正在使用$project阶段返回一种只包含name和brating字段的新型文档。
Mongoengine在这里做不到你想做的事情,所以你有几个选择:
brating字段存储在Post文档上。在创建post和更新$total_score或$total_votes时,将评等初始化为0,同时更新评等。post['name']或post['brating']。.objects查询和排序。如果您有大量的文档,那么最后一步可能会成为一个问题,但对于一小部分,请尝试如下:
posts = Post.objects(types=type).only("name", "total_score", "total_votes")
top_posts = sorted(list(posts),key=lambda p: (p.total_score+60)/(p.total_votes+20))[:100]https://stackoverflow.com/questions/41383077
复制相似问题