【问题标题】:How to count the elements in addToSet array in mongo query using rails 4如何使用rails 4在mongo查询中计算addToSet数组中的元素
【发布时间】:2014-09-15 07:21:50
【问题描述】:
UserStayedTime.collection.aggregate({"$match" => { "rl_mac_id"=>{"$in" => rlids},"starttime"=> { "$gte" => start_date},"endtime" => {"$lte" => end_date}, "stayedtime" => {"$gte" => APPLICATION['defaults']['timeinterval'] } } }, {"$project"=>{"starttime"=>{"$add" => ["$starttime", offset.to_i]}, "visitor_detail_id"=>1}}, { "$group"=> {"_id"=> { "year"=> {"$year"=>"$starttime"},"month"=> {"$month"=>"$starttime"},"day"=> {"$dayOfMonth"=>"$starttime"}, "hour"=>{"$hour"=>"$starttime"}},  "visitors"=> { "$addToSet" => "$visitor_detail_id" }}})

当我写这个查询时,我得到了这个结果:

[{"_id"=>{"year"=>2014, "month"=>9, "day"=>14, "hour"=>9}, "visitors"=>[BSON::ObjectId('54150f6969702d01d4e57b01'), BSON::ObjectId('54150cf669702d01d4197b01')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>14, "hour"=>8}, "visitors"=>[BSON::ObjectId('5415085b69702d01d47d7901'), BSON::ObjectId('541508b869702d01d4a47901'), BSON::ObjectId('5415052a69702d01d4547801'), BSON::ObjectId('541506f669702d01d4f47801'), BSON::ObjectId('5415025b69702d01d4597701'), BSON::ObjectId('5414ffe669702d01d47d7601')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>14, "hour"=>7}, "visitors"=>[BSON::ObjectId('5414fca769702d01d46a7501'), BSON::ObjectId('5414fbf769702d01d4307501'), BSON::ObjectId('5414f97b69702d01d4627401')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>14, "hour"=>6}, "visitors"=>[BSON::ObjectId('5414e5d369702d01d40f6e01'), BSON::ObjectId('5414e51d69702d01d4c76d01')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>22}, "visitors"=>[BSON::ObjectId('5411d53669702d01d4283300'), BSON::ObjectId('5411d53669702d01d4263300')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>14, "hour"=>4}, "visitors"=>[BSON::ObjectId('5414d07169702d01d4786701'), BSON::ObjectId('5414cdf669702d01d4b16601'), BSON::ObjectId('5414cd9a69702d01d48e6601'), BSON::ObjectId('5414cb7c69702d01d4e96501')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>14, "hour"=>1}, "visitors"=>[BSON::ObjectId('5414a40e69702d01d44a5a01')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>13, "hour"=>23}, "visitors"=>[BSON::ObjectId('54148d2169702d01d4765301')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>12, "hour"=>2}, "visitors"=>[BSON::ObjectId('54120af369702d01d4ee5600')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>13, "hour"=>4}, "visitors"=>[BSON::ObjectId('5413827a69702d01d4f6f800')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>10, "hour"=>17}, "visitors"=>[BSON::ObjectId('5410409169702d203c5f0100')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>14, "hour"=>5}, "visitors"=>[BSON::ObjectId('5414dc3b69702d01d4096b01'), BSON::ObjectId('5414dbe669702d01d4ee6a01'), BSON::ObjectId('5414d86969702d01d4e26901')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>13, "hour"=>0}, "visitors"=>[BSON::ObjectId('5413473b69702d01d459e500')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>12, "hour"=>1}, "visitors"=>[BSON::ObjectId('5412065969702d01d4405400'), BSON::ObjectId('5412011869702d01d41e5100'), BSON::ObjectId('5411fe3e69702d01d4774f00')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>13, "hour"=>2}, "visitors"=>[BSON::ObjectId('54135d1469702d01d478ec00'), BSON::ObjectId('541358ec69702d01d40ceb00')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>12, "hour"=>19}, "visitors"=>[BSON::ObjectId('541300e169702d01d43fd100')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>12, "hour"=>5}, "visitors"=>[BSON::ObjectId('54123def69702d01d4d57400')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>12, "hour"=>3}, "visitors"=>[BSON::ObjectId('5412228d69702d01d4aa6400'), BSON::ObjectId('54121b3569702d01d4636000')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>23}, "visitors"=>[BSON::ObjectId('5411e9ae69702d01d4fd4100')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>10, "hour"=>18}, "visitors"=>[BSON::ObjectId('541048f069702d203cae0100')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>5}, "visitors"=>[BSON::ObjectId('5410ead469702d203c530b00'), BSON::ObjectId('5410e96669702d203c360b00'), BSON::ObjectId('5410e74969702d203c0b0b00')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>21}, "visitors"=>[BSON::ObjectId('5411c43a69702d01d4562700')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>19}, "visitors"=>[BSON::ObjectId('5411b28a69702d01d4451b00')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>13, "hour"=>1}, "visitors"=>[BSON::ObjectId('541354b169702d01d4a8e900')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>18}, "visitors"=>[BSON::ObjectId('5411a31869702d01d4f41000')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>10, "hour"=>23}, "visitors"=>[BSON::ObjectId('5410991569702d203ce90400'), BSON::ObjectId('541091ac69702d203c6b0400')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>12, "hour"=>23}, "visitors"=>[BSON::ObjectId('54133ba769702d01d475e100'), BSON::ObjectId('541335fe69702d01d4a2df00')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>2}, "visitors"=>[BSON::ObjectId('5410c0db69702d203c3a0800'), BSON::ObjectId('5410bcf169702d203cf80700'), BSON::ObjectId('5410b89c69702d203c810700')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>13, "hour"=>3}, "visitors"=>[BSON::ObjectId('5413717969702d01d435f300')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>11, "hour"=>0}, "visitors"=>[BSON::ObjectId('5410a38d69702d203cb90500')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>10, "hour"=>22}, "visitors"=>[BSON::ObjectId('5410844b69702d203c890300')]}, {"_id"=>{"year"=>2014, "month"=>9, "day"=>10, "hour"=>14}, "visitors"=>[BSON::ObjectId('5410176a69702d0c45a72e00'), BSON::ObjectId('5410176a69702d0c45a52e00'), BSON::ObjectId('5410176a69702d0c45a32e00'), BSON::ObjectId('54101a8f69702d203c060000'), BSON::ObjectId('5410176a69702d0c45a12e00')]}]

形成这个结果,我只需要根据 (group_by) 小时计算访问者人数。我无法得到这样的结果

 [{"_id"=>{"hour"=>22, "count"=>3 }},{"_id"=>{"hour"=>2, "count"=>5 }},....]

【问题讨论】:

    标签: mongodb ruby-on-rails-4 mongoid mongodb-query aggregation-framework


    【解决方案1】:

    $addToSet 运算符实际上只是另一种获取“不同”分组然后将结果放入数组或“集合”的方式。因此,出于您的目的,这与仅在“visitor_id”上“分组”然后计算不同的出现次数基本相同且更有效:

    UserStayedTime.collection.aggregate(
        { "$match" => { 
            "rl_mac_id" => { "$in" => rlids },
            "starttime"=> { "$gte" => start_date},
            "endtime" => {"$lte" => end_date}, 
            "stayedtime" => {"$gte" => APPLICATION['defaults']['timeinterval'] } 
        }}, 
        { "$project" =>{ 
            "starttime" => { "$add" => ["$starttime", offset.to_i] }, 
            "visitor_detail_id"=>1
        }}, 
        { "$group" => { 
            "_id"=> { 
                "hour" => { "$hour"=>"$starttime"},
                "visitor" => "$visitor_detail_id" 
            }
        }},
        { "$group" => {
            "_id" => "$_id.hour",
            "count" => { "$sum" => 1 }
        }}
    )
    

    这只是一个“双 $group”,因为您获取不同的成员,然后每小时计算它们。当然,假设您的日期范围不与一天重叠,否则您不介意它在哪里。否则,只需像以前一样将其他日期部分添加到分组中。

    你当然可以$unwind“集合”,一旦你产生它,然后再$group计数,但这真的没有必要或像按访问者键分组那样有效。

    【讨论】:

    • 双组,很棒的解决方案:)
    猜你喜欢
    • 2020-11-24
    • 2011-03-19
    • 2016-04-04
    • 2020-11-25
    • 2015-10-12
    • 2022-08-03
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    相关资源
    最近更新 更多