草庐IT

mongodb - 有条件地评估要返回的数组元素

coder 2023-11-03 原文

考虑到以下数据,我想在 MongoDB 的数组字段中返回要从 默认 文档中选择的 ID 的结果。我们将该集合称为 books。示例采集数据如下所示:

[
  {
     name: "Book1",
     refs: [{ oid: "object1" }, { oid: "object2" }, {oid: "object5", default: true }]
  },
  {
    name: "Book2",
    refs: [{ oid: "object3" }, { oid: "object5", default: true }, { oid: "object7" }]
 },
 {
    name: "Book3",
    refs: [{ oid: "object4" }, { oid: "object2" }]
 },
 {
   name: "Book4",
   refs: [{ oid: "object5" }, { oid: "object4", default: true } ]
 }
]

好的。因此,为了简洁起见,其中有很多关键值,但这并没有改变这一点。

这里需要的逻辑如下:

  1. refs 数组字段中查找并返回默认值为 true 的文档
  2. 如果数组中没有匹配的文档,则返回数组中的第一个文档

按照这个逻辑,我真的很想看到返回的内容如下:

[
  {
    name: "Book1"
    refs: [{oid: "object5", default: true }]
  },
  {
    name: "Book2",
    refs: [{ oid: "object5", default: true }]
  },
  {
    name: "Book3",
    refs: [{ oid: "object4" }]
  },
  {
    name: "Book4",
    refs: [{ oid: "object4" }]
  }
]

现在我知道有 $cond聚合管道中的运算符,但这种情况的一部分似乎必然会获得 $slicedefault 属性在文档中不存在的投影上(可能设置为 true 但存在应该足够了)。

此逻辑模式基于使用 $pull 的预期结果删除元素匹配:

oid: "object5"

在每个文档数组之外,然后仍然能够退回到查询中数组的第一个元素

所以我正在寻找一些 strong fu 以便能够返回结果。

并且解决方案不能在主文档中添加另一个引用数组文档中默认 字段值的字段。没有这个实际上是关键,所以 $pull 操作在 multi 中工作文档更新模式。

编辑

这是一个查询,我的意思是当未设置 default 属性时,我想要数组中列出的第一个元素。每次。

字符串是示例数据,因此不依赖于词汇顺序。所有 object# 引用都可能是现实世界中的真实 $oid

这可能最终会成为赏金。如前所述,在更新的容差范围内接受架构更改。在最坏的情况下,调查结果是 JIRA 问题的合理基础。

作为引用,我推出这个是基于我在 this post 上的回答的思考。 ,这主要是关于重新思考架构以适应目标。

好狩猎。

P.S 和 Webscale , 人们。集合的更新需要在没有迭代的情况下发生,因为它们可能真的、真的(哦,网络规模!)数量巨大。

最佳答案

这是一个在 MongoDB 2.4.9 中使用聚合框架的示例,我认为它可以实现您所追求的结果:

db.books.aggregate(

    // Unwind the refs array
    { $unwind: "$refs" },

    // Sort by refs.default descending so "true" values will be first, nulls last
    { $sort: {
        "refs.default" : -1
    }},

    // Group and take the first ref; should either be "default:true" or first element
    { $group: {
        _id: "$_id",
        name: { $addToSet: "$name" },
        refs: { $first: "$refs" }
    }},

    // (optional) Sort by name to match the example output
    { $sort: {
        name: 1,
    }},

    // (optional) Clean up output
    { $project: {
        _id: 0,
        name: 1,
        refs: 1
    }}
)

示例结果:

{
    "result" : [
        {
            "name" : [
                "Book1"
            ],
            "refs" : {
                "oid" : "object5",
                "default" : true
            }
        },
        {
            "name" : [
                "Book2"
            ],
            "refs" : {
                "oid" : "object5",
                "default" : true
            }
        },
        {
            "name" : [
                "Book3"
            ],
            "refs" : {
                "oid" : "object4"
            }
        },
        {
            "name" : [
                "Book4"
            ],
            "refs" : {
                "oid" : "object4",
                "default" : true
            }
        }
    ],
    "ok" : 1
}

注意事项:

  • 这对缺少“default:true”的 refs 的排序顺序行为进行了假设。在简短测试中,原始顺序似乎得以保留,因此数组的“第一个”元素符合预期。

  • 由于使用了聚合运算符,输出 name 是一个单元素数组,而 refs 变成了一个嵌入对象。您无需在聚合框架中进一步操作,只需在应用程序代码中引用正确的字段即可。

关于mongodb - 有条件地评估要返回的数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21525882/

有关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 - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

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

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

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

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

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

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

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

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

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

  10. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

随机推荐