查询Mongo Collection并排除带有未知密钥的嵌入式文档

发布于 2025-02-08 14:50:11 字数 924 浏览 1 评论 0原文

我有一个带有文档的MongoDB集合,例如:

    {
      _id: "...",
      name: "myName",
      versions: {
        1.0.0: {
          status: 'unpublished'
        },
        1.0.1: {
          status: 'published'
        }

        ...

        2.2.0: {
          status: 'unpublished'
        },
        14.3023.1: {
          status: 'published'
        }

        ...
      }

    }

如何查询此集合中的特定文档,其中具有给定名称,例如“ myName”,然后返回该文档,已修改以排除所有版本未发布

我不知道特定版本,即; 1.0.0,1.0.1等。


我的尝试:

    findOne({
      name: "myName"
    }, {
      projection: {
        versions.$.status: {
           $cond: {
               if: { $eq: [ "unpublished", "$versions.$.status" ] },
               then: "$$REMOVE",
               else: "$versions.$.status"
            }
        }
      }
    })

I have a MongoDB collection with documents like:

    {
      _id: "...",
      name: "myName",
      versions: {
        1.0.0: {
          status: 'unpublished'
        },
        1.0.1: {
          status: 'published'
        }

        ...

        2.2.0: {
          status: 'unpublished'
        },
        14.3023.1: {
          status: 'published'
        }

        ...
      }

    }

How can I query a specific document within this collection, that has a given name, say "myName", and return the document, modified to exclude all versions that are unpublished?

I do not know the specific versions beforehand, ie; 1.0.0, 1.0.1 etc.


My attempt:

    findOne({
      name: "myName"
    }, {
      projection: {
        versions.$.status: {
           $cond: {
               if: { $eq: [ "unpublished", "$versions.$.status" ] },
               then: "$REMOVE",
               else: "$versions.$.status"
            }
        }
      }
    })

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

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

发布评论

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

评论(1

吹梦到西洲 2025-02-15 14:50:11

使用动态值作为字段名称通常被视为反图案,应避免降低编写查询的复杂性。但是,您可以使用$ objectToArray$ arraytoObject实现预期行为。

db.collection.aggregate([
  {
    $match: {
      name: "myName"
    }
  },
  {
    "$addFields": {
      "versions": {
        "$objectToArray": "$versions"
      }
    }
  },
  {
    "$addFields": {
      "versions": {
        "$filter": {
          "input": "$versions",
          "as": "ver",
          "cond": {
            $eq: [
              "$ver.v.status",
              "published"
            ]
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "versions": {
        "$arrayToObject": "$versions"
      }
    }
  }
])

这是 mongo playground 供您参考。

Using dynamic value as field name is generally considered as anti-pattern and should be avoided to reduce complexity of composing query. Nevertheless, you can achieve your expected behaviour with $objectToArray and $arrayToObject.

db.collection.aggregate([
  {
    $match: {
      name: "myName"
    }
  },
  {
    "$addFields": {
      "versions": {
        "$objectToArray": "$versions"
      }
    }
  },
  {
    "$addFields": {
      "versions": {
        "$filter": {
          "input": "$versions",
          "as": "ver",
          "cond": {
            $eq: [
              "$ver.v.status",
              "published"
            ]
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "versions": {
        "$arrayToObject": "$versions"
      }
    }
  }
])

Here is the Mongo Playground for your reference.

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