草庐IT

mongodb - 首先按类别分组,然后按周或月分组

coder 2023-10-27 原文

我的文档是这样的:

{
    category: "1",
    timestamp: ISODate("2016-07-16T00:00:00.000Z"),
    amount: 0
},
{
    category: "1",
    timestamp: ISODate("2016-08-18T00:00:00.000Z"),
    amount: 15
},
{
    category: "1",
    timestamp: ISODate("2016-08-01T00:00:00.000Z"),
    amount: 5
},
{
    category: "2",
    timestamp: ISODate("2016-08-18T00:00:00.000Z"),
    amount: 10
}

现在我想首先按类别分组(这已经可行):

{ "$match" : { "timestamp" : { "$gt" : FROM , "$lt" : TO }}},
{ "$sort" : { "timestamp" : 1 }},
{ "$group" : {
    "_id" : "$category",
    "data" : { "$push" : { "timestamp" : "$timestamp" , "amount" : "$amount" }}
}}

然后然后将这些对象分组到data 数组中。获取每周(或每月 - 取决于用户输入)的最大金额。

结果应该是这样的(当按月分组时):

{
    _id: "1",
    data: [
        {
            timestamp: "2016-07",    // could also be an ISODate with
            amount: 0                // first (or last) day of month
        },                           // if that makes things easier
        {
            timestamp: "2016-08",
            amount: 15
        }
    ]
},
{
    _id: "2",
    data: [
        {
            timestamp: "2016-08",
            amount: 10
        }
    ]
}

我尝试展开 data 数组然后再次分组,但这导致一团糟。

希望您有一些不错的想法/解决方案来实现这一点。

编辑:附加问题:

我在 category 上放置了一个索引,它对 $match 工作得很好。在 timestamp 上放置索引以进行排序是否也有用(因为插入顺序可能与时间戳顺序不同),或者该索引不会在聚合中产生任何影响?

最佳答案

我采纳了 Styvane 的回答(再次感谢!)并对其进行了一些简化:

{$match: { timestamp: { $gt: FROM , $lt: TO }}},
{$group: {
    _id: {
        id: "$category",
        timestamp: { $concat: [
            { $toLower: { $year:"$timestamp" } },
            "-",
            { $toLower: { $month: "$timestamp" } }
        ] }
    },
    amount: { $max: "$amount" }
}},
{$sort: { "_id.timestamp": 1 } },
{$group: {
    _id: "$_id.id",
    data: { $push: { timestamp: "$_id.timestamp", amount: "$amount" } }
}}

我尝试在第一个 $group 之前进行 $sort,但有时确实会产生意想不到的结果。尽管我只是将 $sort 放在了 $group 阶段之间。这样,在 timestamp 上建立索引就不再重要了。

关于mongodb - 首先按类别分组,然后按周或月分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39018513/

有关mongodb - 首先按类别分组,然后按周或月分组的更多相关文章

  1. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  2. ruby - 按值降序排列散列,然后按升序键入 ruby - 2

    我有这样的哈希trial_hash={"key1"=>1000,"key2"=>34,"key3"=>500,"key4"=>500,"key5"=>500,"key6"=>500}我按值降序排列:my_hash=trial_hash.sort_by{|k,v|v}.reverse我现在是这样理解的:[["key1",1000],["key4",500],["key5",500],["key6",500],["key3",500],["key2",34]]但我希望当值相同时按键的升序排序。我该怎么做?例如:上面的散列将以这种方式排序:[["key1",1000],["key3",500

  3. ruby - 在 Ruby 中创建按公共(public)键值分组的新哈希 - 2

    假设我有一个在Ruby中看起来像这样的哈希:{:ie0=>"Hi",:ex0=>"Hey",:eg0=>"Howdy",:ie1=>"Hello",:ex1=>"Greetings",:eg1=>"Goodday"}有什么好的方法可以将它变成如下内容:{"0"=>{"ie"=>"Hi","ex"=>"Hey","eg"=>"Howdy"},"1"=>{"ie"=>"Hello","ex"=>"Greetings","eg"=>"Goodday"}} 最佳答案 您要求一个好的方法来做到这一点,所以答案是:一种您或同事可以在六个月后理解

  4. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  5. arrays - 如何在下面的示例中将两个值数组分组为 n 个值数组? - 2

    我已经有很多两个值数组,例如下面的例子ary=[[1,2],[2,3],[1,3],[4,5],[5,6],[4,7],[7,8],[4,8]]我想把它们分组到[1,2,3],[4,5],[5,6],[4,7,8]因为意思是1和2有关系,2和3有关系,1和3有关系,所以1,2,3都有关系我如何通过ruby​​库或任何算法来做到这一点? 最佳答案 这是基本Bron–Kerboschalgorithm的Ruby实现:classGraphdefinitialize(edges)@edges=edgesenddeffind_maximum_

  6. ruby - 如何将相同的相邻数字分组 - 2

    如果至少有两个相邻的数字相同,格式为,我需要打包.这是我的输入:[2,2,2,3,4,3,3,2,4,4,5]以及预期的输出:"2:3,3,4,3:2,2,4:2,5"到目前为止我试过:a=[1,1,1,2,2,3,2,3,4,4,5]a.each_cons(2).any?do|s,t|ifs==t如果相等,也许可以尝试计数器,但那是行不通的。 最佳答案 您可以使用Enumerable#chunk_while(如果你使用的是Ruby>=2.3):a.chunk_while{|a,b|a==b}.flat_map{|chunk|chu

  7. ruby - 根据值然后键对ruby中的哈希进行排序 - 2

    如何在ruby​​中先根据值然后根据键对散列进行排序?例如h={4=>5,2=>5,7=>1}将排序为[[7,1],[2,5],[4,5]]我可以根据值进行排序h.sort{|x,y|x[1]y[1]}但我不知道如何根据值进行排序,然后在值相同时键入 最佳答案 h.sort_by{|k,v|[v,k]}这使用了Array的事实混入Comparable并定义逐元素。注意上面等价于h.sort_by{|el|el.reverse}相当于h.sort_by(&:reverse)这可能会或可能不会更具可读性。如果你知道Hashes一般都是先

  8. ruby - 如何在 Ruby 中将数字分组到不同的桶中 - 2

    我有一个文件,每一行都有数字:010110101311010113114311010431420我想要一个包含每个数字出现次数的散列,在这种情况下:{0101=>2,1010=>2,1311=>2,431=>2,420=>1}我该怎么做? 最佳答案 简单的一行代码,给定一个数组items:items.inject(Hash.new(0)){|hash,item|hash[item]+=1;hash}工作原理:Hash.new(0)创建一个新的Hash,其中访问未定义的键返回0。inject(foo)使用给定的block遍历数组。对于

  9. ruby-on-rails - Ruby On Rails Mongoid 分组依据 - 2

    对于按日期分组,我使用了group_by方法。Example:Product.all.group_by{|d|d.created_at}#returnHash但是kaminari不支持Hash。我使用Mongoid,我需要通过页面导航(kaminari)按日期分组。怎么做到的? 最佳答案 Kaminari只支持数组分页例如Kaminari.paginate_array(an_array).page(1).per(10)group_by不是mongoid方法,它是Array的方法,它是对内存中的所有数据进行分组。为了使用mongoid

  10. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

    我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

随机推荐