草庐IT

MongoDB 分组并从不同文档中减去值

coder 2023-11-02 原文

在我的申请中我有以下文件

{
   "timestamp": ISODate("2015-09-17T21:14:35.0Z"),
   "sensor": "gas-in",
   "value": 2.5,
},
{
   "timestamp": ISODate("2015-09-17T21:14:35.0Z"),
   "sensor": "gas-out",
   "value": 2.0,
},
{
   "timestamp": ISODate("2015-09-17T21:20:35.0Z"),
   "sensor": "gas-in",
   "value": 6.3,
},
{
   "timestamp": ISODate("2015-09-17T21:20:35.0Z"),
   "sensor": "gas-out",
   "value": 0.8,
}

...等...

如何返回差异(gas-in)-(gas-out)按时间戳分组? 我正在尝试编写一个像这样返回它的函数:

{
   "timestamp": ISODate("2015-09-17T21:14:35.0Z"),
   "sensor": "gas-difference",
   "value": 0.5, // is calculated by 2.5 - 2.0
},
{
   "timestamp": ISODate("2015-09-17T21:20:35.0Z"),
   "sensor": "gas-difference",
   "value": 5.5, // is calculated by 6.3 - 0.8
},

...等...

我玩过聚合函数和 $subtract,阅读了其他 SO 问题,但它们似乎没有我的问题的答案。在其他问题中,他们似乎知道要从哪个文件中减去 2 个文件,但在我的情况下,我不知道文件的数量,$timestamp“列”是两个文件的匹配标识符。

谁能帮我解决这个问题?谢谢!

最佳答案

您首先需要的是条件 $sum基于 $cond每个值的分组中的运算符。那你可以单独$subtract :

db.gas.aggregate([
    { "$group": {
        "_id": "$timestamp",
        "gas-in": { 
            "$sum": { 
                "$cond": [
                    { "$eq": [ "$sensor", "gas-in" ] },
                    "$value", 
                    0
                ]
            }
        },
        "gas-out": { 
            "$sum": { 
                "$cond": [
                    { "$eq": [ "$sensor", "gas-out"] },
                    "$value", 
                    0
                ]
            }
        },
    }},
    { "$project": {
        "gasdifference": { "$subtract": [ "$gas-in", "$gas-out" ] }
    }}
])

给出结果:

{ "_id" : ISODate("2015-09-17T21:20:35Z"), "gasdifference" : 5.5 }
{ "_id" : ISODate("2015-09-17T21:14:35Z"), "gasdifference" : 0.5 }

替代方案只是使单个阶段的“气体输出”值为负:

db.gas.aggregate([
    { "$group": {
        "_id": "$timestamp",
        "gasdifference": { 
            "$sum": { 
                "$cond": [
                    { "$eq": [ "$sensor", "gas-in" ] },
                    "$value", 
                    { "$subtract": [ 0, "$value" ] }
                ]
            }
        }
    }}
])

这样会更有效率。

如果您有两个以上可能的“传感器”值,那么您只需“嵌套”$cond 语句:

db.gas.aggregate([
    { "$group": {
        "_id": "$timestamp",
        "gasdifference": { 
            "$sum": { 
                "$cond": [
                    { "$eq": [ "$sensor", "gas-in" ] },
                    "$value", 
                    { "$cond": [
                        { "$eq": [ "$sensor", "gas-out" ] },
                        { "$subtract": [ 0, "$value" ] },
                        0
                    ]}
                ]
            }
        }
    }}
])

由于它们是“三元”运算符 (if-then-else),因此任何进一步的逻辑都属于“else”条件。

关于MongoDB 分组并从不同文档中减去值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32839808/

有关MongoDB 分组并从不同文档中减去值的更多相关文章

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

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

  2. 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"}} 最佳答案 您要求一个好的方法来做到这一点,所以答案是:一种您或同事可以在六个月后理解

  3. 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_

  4. 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

  5. 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遍历数组。对于

  6. 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

  7. ruby - 按相似性对字符串进行分组 - 2

    我有一个字符串数组,数量不多(可能几百个)但通常很长(几百个字符)。这些字符串通常是无意义的,并且彼此不同。但是在一组这样的字符串中,可能300个中有5个具有很大的相似性。事实上,它们是相同的字符串,不同的是格式、标点符号和一些单词..我怎样才能算出那组字符串?顺便说一句,我正在用ruby​​编写,但如果没有别的,伪代码算法就可以了。谢谢 最佳答案 假设您不担心每个单词的拼写错误或其他错误,您可以执行以下操作:构建一个倒排索引,它基本上是一个以单词为键的散列,指向包含该单词的字符串的指针列表(如何处理重复出现由您决定)。要确定与给定

  8. ruby - 续集:如何使用分组和计数 - 2

    简单地说,我如何使用Sequel执行此查询?selecta.id,count(t.id)fromalbumsarightjointrackstont.album_id=a.idgroupbya.id 最佳答案 DB[:albums___a].right_join(:tracks___t,:album_id=>:id).select_group(:a__id).select_more{count(:t__id)} 关于ruby-续集:如何使用分组和计数,我们在StackOverflow上找

  9. ruby - 从另一个哈希中的相应值中减去哈希中的值 - 2

    我希望能够在Ruby中减去两个哈希值并得到第三个哈希值。两个哈希看起来像这样:h1={"Cat"=>100,"Dog"=>5,"Bird"=>2,"Snake"=>10}h1.default=0h2={"cat"=>50,"dog"=>3,"BIRD"=>4,"Mouse"=>75,"Snake"=>10}h2.default=0我希望能够像这样在h1上调用一个方法:h1.difference(h2)并得到这个散列作为结果:{"Cat"=>50,"Dog"=>2,"BIRD"=>-2,"Mouse"=>-75}我想创建一个新的散列,其中包含两个散列中的键,新散列的值是第一个散列中键的值

  10. ruby - 按多个键对哈希数组进行分组 - 2

    我想按多个键分组:订单、idx、帐户等。下面的代码是RubyonRails-HashofArrays,groupbyandsumbycolumnname的修改版本。.谁能推荐一种对多个键进行分组并对多个值求和的方法?例如,在下面的代码中,我只对“订单”进行分组。我想对订单、idx和帐户进行分组。group_hashessome_array,["order","idx","account"]["money","amt"]对比group_hashessome_array,"order","money","amt"代码:some_array=[{"idx"=>"1234","account"

随机推荐