草庐IT

MongoDB 最小/最大聚合

coder 2023-11-04 原文

我有具有这种简化模式的文档:

{
   positon: 10,
   value: 5,
   count: 3
}

我想要计算的是按位置对这些文档进行分组,并找到计数大于 4 但具有 value 的最大 value 小于计数小于 4 的最小 value

这是我所做的,但它不起作用:

{ $group: { 
          _id: {
                   position: "$position",
                 },
          result: {$max: { $cond: [ {$and: [  {$gte: ["$count", 4]}, 
                                              {$lt: ["$value", {$min: { $cond: [ {$lt: ["$count", 4]}, 
                                                                                 { value: "$value" },  
                                                                                 10]
                                                                      }                                                              
                                                               }]
                                             }]},
                                    { value: "$value", nb: "$count"}, 
                                    0] 
                        }
                }
          }
}

有人说 $min 是无效运算符,我不知道如何编写正确的聚合函数。运行 mapreduce 会更好吗?

例如,如果我有那些​​文件

{Position: 10, value: 1, count 5}
{Position: 10, value: 3, count 3}
{Position: 10, value: 4, count 5}
{Position: 10, value: 7, count 4}

我希望结果是

{Position: 10, value: 1, count 4}

因为它是计数大于 4 的“值”的最大值,而且因为值 3 只有 3 个计数,所以值 4 不是我要找的。

最佳答案

至少可以这么说,但我会再解释一下:

你想要:

For each "Position" value find the document whose "value" is less than the the largest "value" of the document with a "count" of less than four, whose own "count" is actually greater than 4.

这听起来像是一道数学考试题,旨在让您对逻辑感到困惑。但是捕获这个意思然后你用以下步骤执行聚合:

db.positions.aggregate([
    // Separate the values greater than and less than 4 by "Position"
    { "$group": {
        "_id": "$Position",
        "high": { "$push": {
            "$cond": [
                { "$gt": ["$count", 4] },
                { "value": "$value", "count": "$count" },
                null
            ]
        }},
        "low": { "$push": {
            "$cond": [
                { "$lt": ["$count", 4] },
                { "value": "$value", "count": "$count" },
                null
            ]
        }}
    }},

    // Unwind the "low" counts array
    { "$unwind": "$low" },

    // Find the "$max" value from the low counts
    { "$group": {
        "_id": "$_id",
        "high": { "$first": "$high" },
        "low":  { "$min": "$low.value" }
    }},

    // Unwind the "high" counts array
    { "$unwind": "$high" },

    // Compare the value to the "low" value to see if it is less than
    { "$project": {
         "high": 1,
         "lower": { "$lt": [ "$high.value", "$low" ] }
    }},

    // Sorting, $max won't work over multiple values. Want the document.
    { "$sort": { "lower": -1, "high.value": -1 } },

    // Group, get the highest order document which was on top
    { "$group": {
        "_id": "$_id",
        "value": { "$first": "$high.value" },
        "count": { "$first": "$high.count" }
    }}
])

所以从文档集:

{ "Position" : 10, "value" : 1, "count" : 5 }
{ "Position" : 10, "value" : 3, "count" : 3 }
{ "Position" : 10, "value" : 4, "count" : 5 }
{ "Position" : 10, "value" : 7, "count" : 4 }

在这种情况下只返回第一个,因为它的值小于“三的计数”文档,而它自己的计数大于 4。

{ "_id" : 10, "value" : 1, "count" : 5 }

我确定这就是您的实际意思。

所以$min的应用和 $max实际上只适用于从文档中获取分组范围之外的离散值时。如果您对文档或整个文档中的多个值感兴趣,那么您正在排序并获得 $first$last分组边界上的条目。

聚合比 mapReduce 快得多,因为它使用 native 代码而不调用 JavaScript 解释器。

关于MongoDB 最小/最大聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23208818/

有关MongoDB 最小/最大聚合的更多相关文章

  1. ruby - 获取数组中的值并最小化某个类属性的最优雅的方法是什么? - 2

    假设我有以下类(class):classPersondefinitialize(name,age)@name=name@age=ageenddefget_agereturn@ageendend我有一组Person对象。是否有一种简洁的、类似于Ruby的方法来获取最小(或最大)年龄的人?如何根据它对它们进行排序? 最佳答案 这样做会:people_array.min_by(&:get_age)people_array.max_by(&:get_age)people_array.sort_by(&:get_age)

  2. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  3. ruby - Rails Elasticsearch 聚合 - 2

    不知何故,我似乎无法获得包含我的聚合的响应...使用curl它按预期工作:HBZUMB01$curl-XPOST"http://localhost:9200/contents/_search"-d'{"size":0,"aggs":{"sport_count":{"value_count":{"field":"dwid"}}}}'我收到回复:{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":90,"max_score":0.0,"hits":[]},"a

  4. c# - Ruby 等效于 C# Linq 聚合方法 - 2

    什么是Linq聚合方法的ruby​​等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj

  5. ruby - 获取数组中值的最大连续出现次数 - 2

    下面有没有更优雅的方法来实现这个:输入:array=[1,1,1,0,0,1,1,1,1,0]输出:4我的算法:streak=0max_streak=0arr.eachdo|n|ifn==1streak+=1elsemax_streak=streakifstreak>max_streakstreak=0endendputsmax_streak 最佳答案 类似于w0lf'sanswer,但通过从chunk返回nil来跳过元素:array.chunk{|x|x==1||nil}.map{|_,x|x.size}.max

  6. ruby - 返回空白页的最小 Capybara/Poltergeist 测试 - 2

    看来我正在回顾SO帖子中采取的步骤:Capybara,PoltergeistandPhantomjsandgivinganemptyresponseinbody.(如果你愿意,可以将其标记为重复,但我包含了一个最小的独立测试用例和版本号。)问题我做错了什么吗?我可以运行另一个可能有助于隔离问题的最小测试吗?文件:pgtest.rbrequire'rubygems'require'capybara'require'capybara/dsl'require'capybara/poltergeist'modulePGTestincludeCapybara::DSLextendselfdeft

  7. ruby - 寻找产品和商店的最佳组合以最小化成本的算法 - 2

    你好,Stackoverflow的人们,我经营一个网站,为用户寻找最便宜的书籍购买地点。这对于单本书来说很容易,但对于多本书来说,有时在一家商店购买一本书而在另一家商店购买另一本书会更便宜。目前我找到了销售用户列表中所有书籍的最便宜的商店,但我想要一个更智能的系统。这里有更多信息:一本书的价格对于一家商店来说是不变的。运费可能会有所不同,具体取决于书籍的数量或书籍的总值(value)。每个商店对象都可以获取一组书籍并返回运费。通常,并非每家书店都出售每一本书。不确定在这里链接到我的站点是否很酷,但它列在我的用户配置文件中。我希望能够找到最便宜的商店和书籍组合。我担心这需要一种蛮力方法-

  8. ruby - capybara 增加最大允许页面加载时间 - 2

    我有一个页面,有时加载时间超过一分钟。假设这是预期的行为并且不会改变。在这些情况下,我得到Net::ReadTimeout。请注意,这是在通过单击上一页上的按钮导航到页面之后,而不是ajax请求。因此Capybara.using_wait_time没有帮助。我尝试了一些激进的方法(其中一些我知道行不通),例如:设置page.driver.browser.manage.timeouts的implicit_wait、script_timeout和page_load。遍历整个对象空间并设置所有Selenium::WebDriver::Remote::Http::Default的timeout

  9. Ruby - 找到哈希最大值的键 - 2

    我有一个散列,我想返回散列最大值的键(或键/值对)。所以,如果只有一个真正的最大值,它将返回那个键;但是,如果有多个具有相同值的键/值对,它将返回所有这些键。我如何在Ruby中完成此操作?my_hash.max_by{|k,v|v}#onlyreturnsonekey/valuepair 最佳答案 如果你想要所有对,我会做类似的事情max=my_hash.values.maxHash[my_hash.select{|k,v|v==max}] 关于Ruby-找到哈希最大值的键,我们在Sta

  10. Ruby:获取具有最大值的哈希对 - 2

    这是一个哈希值,用于跟踪我拥有的每种水果的数量fruits={"apples"=>10,"pears"=>15,"bananas"=>15,"grapes"=>12}我想知道哪种水果我吃得最多。如果有决胜局,则将它们全部归还。 最佳答案 #easymax_quantity=fruits.values.maxmax_fruits=fruits.select{|k,v|v==max_quantity}.keys#fastmax_quantity=-1.0/0.0max_fruits=[]fruits.eachdo|k,v|ifv>max

随机推荐