草庐IT

mongodb - 按匹配条件的嵌入数组元素的数量查找文档

coder 2023-10-28 原文

我是 MongoDB 的新手,需要帮助来完成我的任务:

我正在使用 MongoDB 查询某个人执行的操作。这些操作像这样嵌入到个人文档中:

{
    "_id" : ObjectId("56447ac0583d4871570041c3"),
    "email" : "email@example.net",
    "actions" : [ 
        {
            "name" : "support",
            "created_at" : ISODate("2015-10-17T01:40:35.000Z"),
        }, 
        {
            "name" : "hide",
            "created_at" : ISODate("2015-10-16T01:40:35.000Z")
        },
        {
            "name" : "support",
            "created_at" : ISODate("2015-10-17T03:40:35.000Z"),
        }
    ]
}

一个人可以有许多具有不同 Action 名称的 Action (supporthide 只是两个例子)。

我知道我可以找到至少有一个 support 行为的所有人,如下所示:

db.test.find({'actions.name':'support'})

我想做的是,检索所有具有至少 X 个 support 操作的人。这可能不使用 javascript 语法吗?由于人们可能有数百个 Action ,所以这会很慢。

所以,如果我希望所有人至少有 2 个 support 操作,我知道的唯一方法是使用 js 语法:

db.test.find({$where: function() {
  return this.actions.filter(function(action){
    return action.name = 'support';
  }).length >= 2;
}});

这个查询是否有其他/更好/更快的可能性?

最佳答案

最好的方法是使用 .aggregate()提供对聚合管道的访问的方法。

您可以使用 $match 减小要在管道上处理的文档的大小运算符过滤掉所有不符合给定条件的文档。

您需要使用 $redact运算符仅返回数组中名称为“support”的元素数量为 $gte 的文档2$map此处的运算符返回一组与您的条件相匹配的子文档和 false,您可以使用 $setDifference 轻松删除这些子文档运算符(operator)。当然是 $size运算符返回数组的大小。

db.test.aggregate([
    { "$match": { 
        "actions.name": "support", 
        "actions.2": { "$exists": true } 
    }},
    { "$redact": {
        "$cond": [
            { "$gte": [
                { "$size": { 
                    "$setDifference": [
                        { "$map": { 
                            "input": "$actions", 
                            "as": "action", 
                            "in": { 
                                "$cond": [
                                    { "$eq": [ "$$action.name", "support" ] }, 
                                    "$$action", 
                                    false
                                ]
                            }
                        }}, 
                        [false]
                     ]
                }}, 
                2
            ]}, 
            "$$KEEP", 
            "$$PRUNE"
        ]
    }}
])

从 MongoDB 3.2 开始,这可以使用 $filter 来处理运算符(operator)。

db.test.aggregate([
    { "$match": { 
        "actions.name": "support", 
        "actions.2": { "$exists": true } 
    }},
    { "$redact": {
        "$cond": [
            { "$gte": [
                { "$size": { 
                    "$filter": { 
                        "input": "$actions", 
                        "as": "action", 
                        "cond": { "$eq": [ "$$action.name", "support" ] }
                    }
                }}, 
                2
            ]}, 
            "$$KEEP", 
            "$$PRUNE"
        ]
    }}
])

正如@BlakesSeven 指出的那样:

$setDifference is fine as long as the data being filtered is "unique". In this case it "should" be fine, but if any two results contained the same date then it would skew results by considering the two to be one. $filter is the better option when it comes, but if data was not unique it would be necessary to $unwind at present.

关于mongodb - 按匹配条件的嵌入数组元素的数量查找文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33699193/

有关mongodb - 按匹配条件的嵌入数组元素的数量查找文档的更多相关文章

  1. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  2. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  3. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  4. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  5. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  6. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  7. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  8. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  9. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  10. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

随机推荐