簡體   English   中英

Flask_Mongoengine:使用匯總后不是mongoengine對象

[英]Flask_Mongoengine: Not a mongoengine object after using aggregate

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'>

aggregate函數只是底層pymongo函數的快捷方式。

aggregate返回的文檔可能涉及到$group或其他階段,這意味着它們與您的對象模型沒有關系,因此mongoengine無法將它們轉換為mongoengine對象。

在管道的情況下,您使用$project階段返回一種僅具有namebrating字段的新型文檔。

Mongoengine無法在這里做您想要的事情,因此您有兩種選擇:

  • brating字段存儲在過Post文檔中。 創建帖子時以及更新$total_score$total_votes時,將等級初始化為0。

  • 接受您要取回非mongoengine對象並進行相應處理。 光標將產生普通的python字典,您可以在客戶端代碼中訪問字段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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM