【问题标题】:Using $push with $group with pymongo将 $push 与 $group 与 pymongo 一起使用
【发布时间】:2016-11-29 14:37:14
【问题描述】:

目标

修复我的 make_pipeline() 函数,使用聚合查询计算每个用户的推文数量,将它们添加到数组中并返回推文最多的 5 个用户。

运动

使用聚合查询,计算每个用户的推文数量。 在同一个$group 阶段,使用$push 来累积每个用户的所有推文文本。

将您的输出限制为拥有最多推文的 5 位用户。

您的结果文档应仅包含以下字段:

  • "_id"(用户的网名),
  • "count"(为用户找到的推文数量),
  • "tweet_texts"(为用户找到的推文文本列表)。

背景

为了实现之前的目标,我正在测试以下代码:

def make_pipeline():
    # complete the aggregation pipeline
    pipeline = [
        {"$group": {"_id": "$user.screen_name", "tweet_texts": {"$push": "$text"}, "count": {"$sum": 1}}},
        {"$project": {"_id": "$user.screen_name", "count": 1, "tweet_texts": 1}},
        {"$sort" : {"count" : -1}},
        {"$limit": 5}
    ]
    return pipeline

逻辑

首先,我将所有推文按username 分组。然后,在同一阶段,我将所有发短信的推文推送到tweet_texts,并计算每一次出现的次数。我相信这会给我提供最多推文的用户数量。

然后我做一个投影,只选择我想要的三个字段:

  • _id
  • 计数
  • tweet_texts

我通过排序和限制结果的数量来完成。

问题

我通过了测试,但没有通过提交。我究竟做错了什么? 我现在的错误一定是在第一(组)阶段,但看在上帝的份上,我找不到我做错了什么。

数据样本

{
    "_id" : ObjectId("5304e2e3cc9e684aa98bef97"),
    "text" : "First week of school is over :P",
    "in_reply_to_status_id" : null,
    "retweet_count" : null,
    "contributors" : null,
    "created_at" : "Thu Sep 02 18:11:25 +0000 2010",
    "geo" : null,
    "source" : "web",
    "coordinates" : null,
    "in_reply_to_screen_name" : null,
    "truncated" : false,
    "entities" : {
        "user_mentions" : [ ],
        "urls" : [ ],
        "hashtags" : [ ]
    },
    "retweeted" : false,
    "place" : null,
    "user" : {
        "friends_count" : 145,
        "profile_sidebar_fill_color" : "E5507E",
        "location" : "Ireland :)",
        "verified" : false,
        "follow_request_sent" : null,
        "favourites_count" : 1,
        "profile_sidebar_border_color" : "CC3366",
        "profile_image_url" : "http://a1.twimg.com/profile_images/1107778717/phpkHoxzmAM_normal.jpg",
        "geo_enabled" : false,
        "created_at" : "Sun May 03 19:51:04 +0000 2009",
        "description" : "",
        "time_zone" : null,
        "url" : null,
        "screen_name" : "Catherinemull",
        "notifications" : null,
        "profile_background_color" : "FF6699",
        "listed_count" : 77,
        "lang" : "en",
        "profile_background_image_url" : "http://a3.twimg.com/profile_background_images/138228501/149174881-8cd806890274b828ed56598091c84e71_4c6fd4d8-full.jpg",
        "statuses_count" : 2475,
        "following" : null,
        "profile_text_color" : "362720",
        "protected" : false,
        "show_all_inline_media" : false,
        "profile_background_tile" : true,
        "name" : "Catherine Mullane",
        "contributors_enabled" : false,
        "profile_link_color" : "B40B43",
        "followers_count" : 169,
        "id" : 37486277,
        "profile_use_background_image" : true,
        "utc_offset" : null
    },
    "favorited" : false,
    "in_reply_to_user_id" : null,
    "id" : NumberLong("22819398300")
}

请帮忙!

【问题讨论】:

  • 我还是不明白这个错误。你又在哪里得到错误?
  • 在你的$project中,不应该是{"$project": {"_id": 1...}}吗?
  • 这里还需要项目阶段吗?
  • 没有语法错误,代码也没有爆炸。它根本不会返回预期的结果。它返回的用户显然不是推文最多的用户。至于$project,我相信我需要它,因为答案的格式只需要三个字段,而且我正在重命名_id字段。
  • 正确的管道应该是pipeline = [ {"$group": {"_id": "$user.screen_name", "tweet_texts": {"$push": "$text"}, "count": {"$sum": 1}}}, {"$sort" : {"count" : -1}}, {"$limit": 5} ]

标签: python mongodb mongodb-query pymongo


【解决方案1】:

$project 步骤是多余的,因为 $group 管道已经生成了这三个字段,因此不需要前面的 $project 舞台。

正确的管道应该是

pipeline = [ 
    {
        "$group": {
            "_id": "$user.screen_name", 
            "tweet_texts": { "$push": "$text" }, 
            "count": { "$sum": 1 }
        }
    }, 
    { "$sort" : { "count" : -1 } }, 
    { "$limit": 5 } 
] 

您的 $project 管道不起作用,因为之前的 $group 管道没有生成您尝试用作 @ 的任何字段 "$user.screen_name" $project 管道中的 987654335@ 字段。

但是,如果您想包含 $project 步骤,那么工作管道应该如下所示:

pipeline = [ 
    {
        "$group": {
            "_id": "$user.screen_name", 
            "tweet_texts": { "$push": "$text" }, 
            "count": { "$sum": 1 }
        }
    }, 
    { "$project": { "count": 1, "tweet_texts": 1 } },
    { "$sort" : { "count" : -1 } }, 
    { "$limit": 5 } 
] 

【讨论】:

  • 当我要发布我的答案时,您真的必须发布答案吗? :P 无论如何,荣誉++
  • 不用担心 :) 由于@chidram 拼写错误,我之前没有收到解释答案的通知,但现在一切都很好,很高兴您找到了解决方案。
【解决方案2】:

阅读cmets

阅读cmets我发现

pipeline = [
        {"$group": {"_id": "$user.screen_name", "tweet_texts": {"$push": "$text"}, "count": {"$sum": 1}}},
        {"$project": {"_id": "$user.screen_name", "count": 1, "tweet_texts": 1}},
        {"$sort" : {"count" : -1}},
        {"$limit": 5}
    ]

实际上应该改为:

pipeline = [ 
        {"$group": {"_id": "$user.screen_name", "tweet_texts": {"$push": "$text"}, "count": {"$sum": 1}}}, 
        {"$sort" : {"count" : -1}}, 
        {"$limit": 5}
    ]

为什么?

完整答案及解释见答案:

故事的结论是我错误地使用了$project阶段。不仅是一开始就不需要,为了使它具有幂等性,它应该是

{"$project": {"_id": "$_id", "count": 1, "tweet_texts": 1}},

我也强烈推荐他的回答:

特别感谢

以下用户值得称赞++:

为了指引我走上正确的道路!

【讨论】:

    猜你喜欢
    • 2014-05-09
    • 2017-10-11
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 2021-04-03
    • 2016-04-03
    相关资源
    最近更新 更多