从3倍嵌套级数组文档中获取所有级别的字段

发布于 2025-02-13 18:24:18 字数 1486 浏览 0 评论 0原文

我有以下文档类型:

{
_id: 1,
"_a": [
{
"_aId": {
  "CC": "CA"
},
"_p": [
  {
    "_pId": {
      "CC": "CA",
       "SN":1
    },
    "s": {
      "c": {
        "t": [
          {
            sId: 1,
            language: "CA",
            format: "A4"
          },
          {
            sId: 2,
            language: "JP",
            format: "A4"
          }
        ]
      },
      "a": {
        "t": [
          {
            sId: 4,
            language: "CA",
            "format": "A4"
          },
          {
            sId: 5,
            language: "EN",
            "format": "A3"
          }
        ]
      },
      "d": {
        "t": [
          {
            sId: 10,
            language: "CA",
            "format": "A4"
          }
        ]
      }
    }
  }
 ]
 }
 ]
}

我需要更快的解决方案来提取所有子图表SID& _PID 语言:“ CA”& 格式:“ A4”带有的文档“ _ a._p._pid.cc”:“ CA”

因此预期的输出需要如下:

{_pid:{CC:"CA",SN:1},sId:1}
{_pid:{CC:"CA",SN:1},sId:4}
{_pid:{CC:"CA",SN:1},sId:10}

playground

感谢@nimrod,我有了初始解决方案在这里,但不确定如何包括_ pid也不会降低性能...

(我正在使用mongodb 4.0)

I have the following document type:

{
_id: 1,
"_a": [
{
"_aId": {
  "CC": "CA"
},
"_p": [
  {
    "_pId": {
      "CC": "CA",
       "SN":1
    },
    "s": {
      "c": {
        "t": [
          {
            sId: 1,
            language: "CA",
            format: "A4"
          },
          {
            sId: 2,
            language: "JP",
            format: "A4"
          }
        ]
      },
      "a": {
        "t": [
          {
            sId: 4,
            language: "CA",
            "format": "A4"
          },
          {
            sId: 5,
            language: "EN",
            "format": "A3"
          }
        ]
      },
      "d": {
        "t": [
          {
            sId: 10,
            language: "CA",
            "format": "A4"
          }
        ]
      }
    }
  }
 ]
 }
 ]
}

And I need faster solution to extract all subdocuments sId & _pid for language:"CA" & format:"A4" for documents with "_a._p._pid.CC":"CA"

So the expected output need to look as follow:

{_pid:{CC:"CA",SN:1},sId:1}
{_pid:{CC:"CA",SN:1},sId:4}
{_pid:{CC:"CA",SN:1},sId:10}

Playground

Thanks to @Nimrod I have the initial solution here, but not sure how to include the _pid as well so it does not reduce performance ...

(I am using MongoDB 4.0)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏九 2025-02-20 18:24:18

我不确定性能,但是您可以尝试一个选项,

  • $ match您的状况,
  • $ project
    • $ redus要迭代_a的循环
      • $ filter要迭代_p的循环,然后通过“ _ pid.cc”过滤它:“ ca”
      • $ concatrays到上述过滤结果,并具有先前的过滤结果
  • $ project,此过程很难在此处描述,但它只是在结果中过滤了您的预期
  • 字段_a
db.collection.aggregate([
  { $match: { "_a._p._pId.CC": "CA" } },
  {
    $project: {
      _id: 0,
      _a: {
        $reduce: {
          input: "$_a",
          initialValue: [],
          in: {
            $concatArrays: [
              "$value",
              {
                $filter: {
                  input: "$this._p",
                  cond: { $eq: ["$this._pId.CC", "CA"] }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      _a: {
        $reduce: {
          input: "$_a",
          initialValue: [],
          in: {
            $concatArrays: [
              "$value",
              {
                $map: {
                  input: {
                    $reduce: {
                      input: { $objectToArray: "$this.s" },
                      initialValue: [],
                      in: {
                        $concatArrays: [
                          "$value",
                          {
                            $filter: {
                              input: "$this.v.t",
                              cond: {
                                $and: [
                                  { $eq: ["$this.format", "A4"] },
                                  { $eq: ["$this.language", "CA"] }
                                ]
                              }
                            }
                          }
                        ]
                      }
                    }
                  },
                  as: "p",
                  in: {
                    _pId: "$this._pId",
                    sId: "$p.sId"
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  { $unwind: "$_a" }
])

playground

I am not sure about performance, but you can try an option,

  • $match your condition,
  • $project,
    • $reduce to iterate loop of _a
      • $filter to iterate loop of _p and filter it by "_pId.CC": "CA"
      • $concatArrays to concat above filtered result with previous filtered result
  • $project, the process is hard to describe here but it just filters your expected fields in the result
  • $unwind to deconstruct the _a
db.collection.aggregate([
  { $match: { "_a._p._pId.CC": "CA" } },
  {
    $project: {
      _id: 0,
      _a: {
        $reduce: {
          input: "$_a",
          initialValue: [],
          in: {
            $concatArrays: [
              "$value",
              {
                $filter: {
                  input: "$this._p",
                  cond: { $eq: ["$this._pId.CC", "CA"] }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      _a: {
        $reduce: {
          input: "$_a",
          initialValue: [],
          in: {
            $concatArrays: [
              "$value",
              {
                $map: {
                  input: {
                    $reduce: {
                      input: { $objectToArray: "$this.s" },
                      initialValue: [],
                      in: {
                        $concatArrays: [
                          "$value",
                          {
                            $filter: {
                              input: "$this.v.t",
                              cond: {
                                $and: [
                                  { $eq: ["$this.format", "A4"] },
                                  { $eq: ["$this.language", "CA"] }
                                ]
                              }
                            }
                          }
                        ]
                      }
                    }
                  },
                  as: "p",
                  in: {
                    _pId: "$this._pId",
                    sId: "$p.sId"
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  { $unwind: "$_a" }
])

Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文