【问题标题】:MongoDB aggregation query - return all items inside nested subdocumentMongoDB聚合查询 - 返回嵌套子文档中的所有项目
【发布时间】:2021-07-27 08:26:50
【问题描述】:

基本上,我有一个嵌套的对象数组。我想从这些对象中提取信息,并将所有结果作为数组返回。

这是我的数据:

[
  {
    "_id": "608642db80a36336946620aa",
    "title": "titleHere",
    "types": {
      "flashcardReversed": [
        {
          "normal": { // the data inside of "normal" should become its own object in the returned array
            "_id": "608d5b290e635ece6828141X",
            "front": "2front",
            "back": "2back"
          },
          "reversed": { // the data inside of "reversed" should become its own object in the returned array
            "_id": "608t5b290e635ece6828141Y",
            "front": "2frontReversed",
            "back": "2backReversed"
          }
        },
        {
          "normal": {
            "_id": "608a5b31a3f9806de253726X",
            "front": "2front2",
            "back": "2back2"
          },
          "reversed": {
            "_id": "608a5b31a3f9806de253726Y",
            "front": "2frontReversed2",
            "back": "2backReversed2"
          }
        }
      ]
    }
  }
]

这是想要的结果:

[
  {
    "flashcardReversed": [
      {
        "_id": "608d5b290e635ece6828141X",
        "front": "2front",
        "back": "2back"
      },
      {
        "_id": "608t5b290e635ece6828141Y",
        "front": "2frontReversed",
        "back": "2backReversed"
      },
      {
        "_id": "608t5b290e635ece6828141Y",
        "front": "2frontReversed",
        "back": "2backReversed"
      },
      {
        "_id": "608a5b31a3f9806de253726Y",
        "front": "2frontReversed2",
        "back": "2backReversed2"
      }
    ]
  }
]

我目前的尝试:https://mongoplayground.net/p/k3Fjd59KMKg 我曾尝试通过各种方法合并$card$card2 文档,然后使用$replaceRoot 来创建所需的结果 - 但经过长时间的尝试,我没有成功。

关于我的用例的一些说明 - 我将在$facet 中使用这个管道 flashcardReversed 内部会有很多对象,都是从同一个 Mongoose Schema 创建的

文档最多应包含 ~2000 张卡片。我需要在反应网站中使用的结果。我应该担心这个搜索的效率吗? (如果这本身就是一个问题,我很乐意将其移动)。

如果我的 Mongoose Schema 有帮助,请告诉我,我可以添加它们。

感谢所有帮助,

- Riley Swinson

【问题讨论】:

  • 原版中是否总是“正常”和“反转”键?还是可以有更多?
  • @CodyG 可以有很多文档,都具有相同的结构。我会澄清我的帖子。谢谢!

标签: javascript mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

我能够想出这个查询来得到想要的结果

    db.collection.aggregate([
  {
    "$unwind": "$types.flashcardReversed"
  },
  {
    "$project": {
      "flashcardReversed": {
        "$map": {
          "input": {
            "$objectToArray": "$types.flashcardReversed"
          },
          "as": "elem",
          "in": "$$elem.v"
        }
      }
    }
  },
  {
    "$unwind": "$flashcardReversed"
  },
  {
    "$group": {
      "_id": 1,
      "flashcardReversed": {
        "$push": "$flashcardReversed"
      }
    }
  },
  {
    "$project": {
      "_id": 0
    }
  }
])

上述管道的解释:

  1. 使用$unwind 将数组划分为其元素
  2. 使用$project$mapflashcardReversed 对象转换为值数组。使用$map 允许管道处理正常和反转之上的任何其他键
  3. 使用$unwind再次拆分步骤2中形成的flashcardReversed数组
  4. 使用 $group$push 累加器将 flashcardReversed 的所有值添加到单个数组中
  5. 使用$project 从响应中删除_id 字段

这是一个 Mongodb 游乐场link 相同

【讨论】:

    【解决方案2】:

    这可以通过

    • $unwind 拆分闪存卡阵列
    • $project 将包含 normal/reverse 的对象转换为数组
    • $unwind 创建的数组
    • $group by _id 并收集数组中的值
    db.collection.aggregate([
      {$unwind: "$types.flashcardReversed"},
      {$project: {
          flashcardReversed: [
            "$types.flashcardReversed.normal",
            "$types.flashcardReversed.reversed"
          ]
      }},
      {$unwind: "$flashcardReversed"},
      {$group: {
          _id: "$_id",
          flashcardReversed: {$push: "$flashcardReversed"}
      }}
    ])
    

    【讨论】:

    • 感谢您的回答 - 我很感激。我注意到我的问题中有一个错误——因为我使用的是$facet,所以我已经有了"flashcardReversed" as the parent: []。我将如何在结果中返回 flashcardReversed 数组中的内容?
    • 使用 $replaceRoot 阶段
    • 已尝试,但出现错误 $replaceRoot must be of type object。尝试使用 $arrayToObject,但我认为我需要一个不同的对象结构才能工作?
    • {$replaceRoot:{newRoot:"$flashcardReversed"}}
    • 是的,正是我尝试过的,但仍然返回错误 - mongoplayground.net/p/CiaOOrzzw5i。目标是从数组中删除所有内容 - 因为 $facet 已经是一个数组 this 似乎它可能是一个解决方案
    猜你喜欢
    • 2023-03-30
    • 2019-02-16
    • 1970-01-01
    • 2017-04-10
    • 2021-11-12
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    相关资源
    最近更新 更多