将 $lookup 结果合并到现有数组

2024-05-05

我是 mongo 新手,我需要你的帮助。

我有收藏学习计划。这是示例文档:

{
    "_id" : "dGFY",
    "garranti" : [
        {
            "typ" : {
                "sk" : "garant",
                "en" : "Chairman of study board"
            },
            "id" : "1025769"
        },
        {
            "typ" : {
                "sk" : "predseda odborovej komisie",
                "en" : "Chairman of study board"
            },
            "id" : "1025769"
        }
    ]
}

接下来我有收藏osoby.
示例文档:

{
    "_id" : "1025769",
    "plneMeno" : "prof. RNDr. Peter Moczo, DrSc.",
    "priezvisko" : "Moczo",
    "meno" : "Peter",
    "jeGarantProgramu" : "dGFY/x"
}

我需要的是添加文档osoby到数组中对应的文档garranti(其中studijneProgramy.garanti.id == osoby._id)。 所以这是我想要的结果:

{
    "_id" : "dGFY",
    "garranti" : [
        {
            "typ" : {
                "sk" : "garant",
                "en" : "Chairman of study board"
            },
            "id" : "1025769"
            "garant":{
                "_id" : "1025769",
                "plneMeno" : "prof. RNDr. Peter Moczo, DrSc.",
                "priezvisko" : "Moczo",
                "meno" : "Peter",
                "jeGarantProgramu" : "dGFY/x"
            }
        },
        {
            "typ" : {
                "sk" : "predseda odborovej komisie",
                "en" : "Chairman of study board"
            },
            "id" : "1025769"
            "garant":{
                "_id" : "1025769",
                "plneMeno" : "prof. RNDr. Peter Moczo, DrSc.",
                "priezvisko" : "Moczo",
                "meno" : "Peter",
                "jeGarantProgramu" : "dGFY/x"
            }
        }
    ]
}

我尝试了这个聚合,但它替换了内容garranti.

db.studijneProgramy.aggregate([
{
    $lookup:
    {
        from:"osoby", 
        localField:"garranti.id",
        foreignField:"_id", 
        as:"garranti.garant"
    }
 }
]
).pretty()

任何帮助将不胜感激!


MongoDB $lookup https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/不会使用“查找”集合中的匹配项“更新”现有数组中的元素。它会only输出与给定条件匹配的“数组”,与您拥有的值的“现有数组”或奇异值相匹配。

为了将条目与“服务器”“结婚”$lookup https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/操作,您必须继续执行以下选项之一才能以您想要的形式返回。

$首先展开数组

最简单的形式是简单地更改文档的结构,以便源中的每个数组成员都是它的首先自己的文档,在您真正尝试“结合”相关信息之前:

db.studijneProgramy.aggregate([
  { "$unwind": "$garranti" },
  { "$lookup": {
    "from": "osoby",
    "as": "garranti.garrant",
    "localField": "garranti.id",
    "foreignField": "_id"
  }},
  { "$unwind": "$garranti.garrant" },
  { "$group": {
    "_id": "$_id",
    "garranti": { "$push": "$garranti" }
  }}
])

由于原始数组材料现在是单个文档,因此每个文档仅接收来自连接集合的匹配“数组”。这个会$unwind https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/再次使用$group https://docs.mongodb.com/manual/reference/operator/aggregation/group/为了$push https://docs.mongodb.com/manual/reference/operator/aggregation/push/到带有“连接”条目的最终数组形式。

关联“数组”

在支持它的版本中有点花哨的是使用以下功能$indexOfArray https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfArray/ and $arrayElemAt https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfArray/为了“匹配”输出数组$lookup https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/到文档中现有的数组条目:

db.studijneProgramy.aggregate([
  { "$lookup": {
    "from": "osoby",
    "as": "related",
    "localField": "garranti.id",
    "foreignField": "_id"
  }},
  { "$project": {
    "garranti": {
      "$map": {
        "input": "$garranti",
        "in": {
          "typ": "$$this.typ",
          "id": "$$this.id",
          "garrant": {
            "$arrayElemAt": [
              "$related",
              { "$indexOfArray": [ "$related._id", "$$this.id" ] }
            ]
          }
        }
      }
    }
  }}
])

因此查找返回“匹配数组”(related)然后您“查找”这些匹配的条目并将它们转置到原始文档数组中$map https://docs.mongodb.com/manual/reference/operator/aggregation/map/。当然这需要额外的$project https://docs.mongodb.com/manual/reference/operator/aggregation/project/stage 或类似的内容,以便重塑文档结果,因为您无法“定位”现有数组的每个元素$lookup https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/输出如前所述。

这实际上是“服务器”上某些库(例如“mongoose”)为“客户端上的连接模拟”所做的直接关联。实际上,“外部”条目被“映射”到现有数组上。

子管道处理

有点花哨和冗长的是使用“子管道”处理的另一种选择不相关子查询 https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#uncorrelated-subquery从 MongoDB 3.6 及以上版本可用。这里我们基本上是在“子管道”中进行操作$lookup https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/而不是在后续聚合阶段进行处理:

db.studijneProgramy.aggregate([
  { "$lookup": {
    "from": "osoby",
    "as": "garranti",
    "let": { "garranti": "$garranti" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": [ "$_id", "$$garranti.id" ] } 
      }},
      { "$addFields": {
        "docs": {
          "$filter": {
            "input": "$$garranti",
            "cond": {
              "$eq": [ "$$this.id", "$_id" ]
            }
          }
        }
      }},
      { "$unwind": "$docs" },
      { "$replaceRoot": {
        "newRoot": {
          "$mergeObjects": [
            "$docs",
            { "garrant": {
              "$arrayToObject": {
                "$filter": { 
                  "input": { "$objectToArray": "$$ROOT" },
                  "cond": { "$ne": [ "$$this.k", "docs"] }
                }
              }
            }}
          ]
        }
      }}
    ]
  }}
])

这种方式将操作“彻底”转变,并有效地将“源文档”中的“匹配数组元素”作为数组放入每个匹配的外部元素中。

然后处理有效地使用$unwind https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/在过滤后的源列表上,然后合并外部集合中的内容,因此现在看来$lookup https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/“输出数组”实际上是来自“本地数组”的数据,现在与“外部内容”“合并”。

实际上,这只是对相同内容的更奇特的调用$map https://docs.mongodb.com/manual/reference/operator/aggregation/map/上面的过程,但是对条目进行“关联”before结果与原始父文档合并,覆盖原始数组属性。


我认为某个地方有一个 JIRA 可以解决这个问题,但我有一种感觉“按设计工作”所有此类报告均已标记,因此不太可能改变目前的做法。

因此,您的误解是“连接”会“自动”与数组条目“合并”。它不是。

如果您实际上想“合并数组输出”,那么上面的方法就是“服务器”方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 $lookup 结果合并到现有数组 的相关文章

  • Meteor 独特客户端集合的发布/订阅策略

    使用 Meteor 我想知道如何最好地处理共享相同服务器端数据库集合的不同客户端集合 考虑以下示例 我有一个User集合 在我的客户端我有一个好友用户列表我有一个搜索功能 可以对整个用户数据库执行查询 返回一个与查询匹配的用户名列表 在发布
  • Mongo:按键查询一层深

    是否可以在 Mongo 查询中使用 存在 之类的内容来根据 ID 返回此记录 就像是选择 ids 包含密钥 123456 的位置 department Digging ids 123456 color blue 123457 color r
  • Morphia - 未在 dbObj 中找到定义的类

    我有一个相当有趣的问题 当尝试从 Mongo 实例加载模型时 Morphia 会抛出以下错误 22 17 13 WARN Class not found defined in dbObj java lang ClassNotFoundExc
  • 如何访问 Pandas DataFrame 中嵌入的 json 对象?

    TL DR 如果 Pandas DataFrame 中加载的字段本身包含 JSON 文档 那么如何以类似 Pandas 的方式使用它们 目前我直接从 Twitter 库转储 json 字典结果 twython https github co
  • 猫鼬模式创建

    我刚刚开始使用猫鼬 我有一个使用 mongoose 的创建脚本 它使用示例数据创建模式和数据库 现在我编写实际的应用程序 我是否需要在每次应用程序运行时创建架构对象 或者它是否已经以某种方式可用 换句话说 我是否需要在每个使用 mongoo
  • MongoDb聚合

    如何使用 mongoDb 聚合编写模拟查询 select count as ccount from a group by a someField order by ccount desc limit 1 使用 mongoDb 中的 grou
  • 在 AWS EKS 集群中安装 mongodb 时出错 - “运行 PreBind 插件 VolumeBinding:绑定卷:超时 > 等待条件”

    我尝试按照给定的链接在 EKS 集群中安装 mongodb 使用 mongodb kubernetes operator https github com mongodb mongodb kubernetes operator https
  • Mongodb聚合框架:$group是否使用索引?

    我正在尝试使用聚合框架 match and group阶段 做 group阶段使用索引数据 我正在使用最新的可用 mongodb 版本 2 5 4 group不使用索引数据 来自 mongoDBdocs http docs mongodb
  • Mongoose 多个连接

    目前我的连接有这个代码猫鼬 js var mongoose require mongoose var uriUtil require mongodb uri var mongodbUri mongodb localhost db name
  • MongoDB - 编辑器变量 - MongoDB shell - Windows 7

    EDITOR 变量功能真的可以在 Windows 7 上使用吗 我正在读一篇文章 说一旦我们设置了 EDITOR 变量在 mongorc js 中 我们只需在 shell 中输入 编辑变量名 and var name将被加载到编辑器中 在我
  • Mongo JSON 文档 -> JSON -> BSON

    我正在使用 Node js 构建一个使用 mongodb 的 Web 套接字服务器 我使用 node mongodb native 作为访问 mongodb 的库 当我对数据库中的对象调用 console log sys inspect i
  • Windows 7 机器上的 MongoDB:无法建立连接

    在 Windows 7 机器上使用 mongod exe 启动 Mongo 后 我尝试启动 mongo shell 但失败并出现以下错误 无法连接到 127 0 0 1 27017 原因 errno 10061 否 由于目标机器主动拒绝而无
  • MacOS 每秒唤醒次数错误

    构建 Rails 应用程序 ruby 2 4 0p0 Rails 5 1 4 并使用我的 Macbook Air MacOS High Sierra 10 13 2 进行本地测试 我不断遇到此问题 过去 241 秒内有 45001 次唤醒
  • Mongoose嵌入式文档更新

    我在嵌入式文档更新方面遇到问题 我定义的架构 var Talk new Schema title type String required true content type String required true date type D
  • MongoDB $geoIntersects 不适用于包含负顶点的多边形

    我已在数据库中存储了跨越 x 轴和 y 轴的多边形 并且我想搜索包含给定点的多边形 为此 我使用 geoIntersects 运算符来指定一个点 但是 当多边形穿过轴时 MongoDB 不会返回任何多边形 我可以对查询或架构进行任何小的更改
  • 如何使用 pymongo 在 mongodb 中查询日期?

    我试图在 mongodb 中执行查询日期 但结果始终为空 我的查询如下 in the begin code def init self self now datetime now self db conexaoMongo self hora
  • Mongodump之后,调用MongoRestore挂起

    我们正在尝试在相对较小的数据库上做一个简单的 MongoDump 我们的步骤很简单 export 从目标机器上删除现有数据库 在目标机器上导入 MongoDump 完美执行 mongodump out root mongo prod DB
  • Node.js 检测两个猫鼬查找何时完成

    我正在尝试使用自动完成功能初始化两个输入library https www devbridge com sourcery components jquery autocomplete 当我加载页面时 我将触发 Ajax 来初始化两个输入文本
  • 获取对象数组中每个嵌套对象的虚拟属性?

    所以我知道如何获取单个虚拟属性 如 Mongoose 文档中所述 PersonSchema virtual name full get function return this name first this name last 但如果我的
  • 如何处理 MongoDB 的断开连接错误

    我在 Node js 进程中看到了这个未捕获的异常 Uncaught exception Error read ETIMEDOUT at TCP onStreamRead internal stream base commons js 16

随机推荐