从3倍嵌套阵列中提取值(Mongod 4.0.23)

发布于 2025-02-12 16:08:04 字数 1382 浏览 1 评论 0原文

请帮助,我有以下文档类型:

{
_id: 1,
"_a": [
  {
    "_aId": {
      "CC": "CA"
    },
    "_p": [
      {
        "_pId": {
          "CC": "CA"
        },
        "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"
              }
            ]
          }
        }
      }
    ]
    }
  ]
 }

我需要更快的解决方案来提取所有语言的子插图:“ ca”&格式:使用“ _a._p._pid.cc”的文档“ A4”:“ CA”

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

  {sId:1}
  {sId:4}
  {sId:10}

我在“ _a._p._pid.cc”上有一个索引,我已经尝试过2x $放松,但是收集很大,需要一些时间才能放松,欢迎任何建议吗?

playground

mongod 4.0.23

Please, help , I have following document type:

{
_id: 1,
"_a": [
  {
    "_aId": {
      "CC": "CA"
    },
    "_p": [
      {
        "_pId": {
          "CC": "CA"
        },
        "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 for language:"CA" & format:"A4" for documents with "_a._p._pid.CC":"CA"

So the expected output need to look as follow:

  {sId:1}
  {sId:4}
  {sId:10}

I have an index on "_a._p._pId.CC" and I have tried with 2x $unwind , but collection is pretty big and it take some time to unwind , any suggestion highly is welcome?

Playground

mongod 4.0.23

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

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

发布评论

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

评论(1

得不到的就毁灭 2025-02-19 16:08:04

edit :rmaved $ first匹配MongoDB版本3.6:

一个选项是:

  1. $降低 res res _a._p.s
  2. 使用$ objecttoarry,因为有不同的密钥名称。
  3. $降低再次获得t s的平坦数组。
  4. $ filter仅保留想要的项目的数组。
  5. 格式化响应。
db.collection.aggregate([
  {$project: {
      _id: 0,
      res: {$reduce: {
          input: "$_a",
          initialValue: [],
          in: {$concatArrays: [
              "$value",
              {$reduce: {
                  input: "$this._p",
                  initialValue: [],
                  in: {$concatArrays: ["$value", ["$this.s"]]}
                }
              }
            ]
          }
        }
      }
    }
  },
  {$project: {res: {$map: {input: "$res", in: {$objectToArray: "$this"}}}}},
  {$project: {
      res: {
        $reduce: {
          input: "$res",
          initialValue: [],
          in: {$concatArrays: [
              "$value",
              {$reduce: {
                  input: "$this",
                  initialValue: [],
                  in: {$concatArrays: ["$value", "$this.v.t"]}}
              }
            ]
          }
        }
      }
    }
  },
  {$project: {
      res: {$filter: {
          input: "$res",
          cond: {
            $and: [{$eq: ["$this.language", "CA"]}, {$eq: ["$this.format", "A4"]}]
          }
        }
      }
    }
  },
  {$unwind: "$res"},
  {$project: {sId: "$res.sId"}}
])

查看其在

Edit: rmoved $first to match mongodb version 3.6:

One option is:

  1. $reduce to res the objects under _a._p.s
  2. Use $objectToArry, since there are different key names.
  3. $reduce again to get a flat array of ts.
  4. $filter the array to keep only wanted items.
  5. Format the response.
db.collection.aggregate([
  {$project: {
      _id: 0,
      res: {$reduce: {
          input: "$_a",
          initialValue: [],
          in: {$concatArrays: [
              "$value",
              {$reduce: {
                  input: "$this._p",
                  initialValue: [],
                  in: {$concatArrays: ["$value", ["$this.s"]]}
                }
              }
            ]
          }
        }
      }
    }
  },
  {$project: {res: {$map: {input: "$res", in: {$objectToArray: "$this"}}}}},
  {$project: {
      res: {
        $reduce: {
          input: "$res",
          initialValue: [],
          in: {$concatArrays: [
              "$value",
              {$reduce: {
                  input: "$this",
                  initialValue: [],
                  in: {$concatArrays: ["$value", "$this.v.t"]}}
              }
            ]
          }
        }
      }
    }
  },
  {$project: {
      res: {$filter: {
          input: "$res",
          cond: {
            $and: [{$eq: ["$this.language", "CA"]}, {$eq: ["$this.format", "A4"]}]
          }
        }
      }
    }
  },
  {$unwind: "$res"},
  {$project: {sId: "$res.sId"}}
])

See how it works on the playground example

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