【问题标题】:Exclude nested documents based on a condition根据条件排除嵌套文档
【发布时间】:2019-03-26 16:58:56
【问题描述】:

我有一份格式如下的文件

{
  "_id": "5c9a53b348a0ac000140b5f9",
  "e": [
    {
      "_id": "d6c74cd5-5808-4b0c-b857-57ddbcc72ce5",
      "isDeleted": true
    },
    {
      "_id": "d6c74cd5-5808-4b0c-b857-57ddbcc72ce6",
      "isDeleted": false
    }
  ]
}

每个文档都有一个元素列表,每个元素可能会或可能不会被删除。默认情况下,我不想返回已删除的数据。现在,我在服务器端过滤它们,但这仍然意味着大量数据被不必要地传输。是否可以在数据库中排除这些数据?

我查看了$elemMatch,但它只返回一个值,因此它看起来不像是适合这项工作的工具。

有没有办法将包含嵌套文档数组的文档投影为仅包含符合特定条件的那些子文档?

【问题讨论】:

  • 您希望上述示例文档的输出是什么?
  • @AnthonyWinzlet 除了e 集合之外,文档中的每个字段都应该只包含具有isDeleted == false 的元素。

标签: mongodb projection


【解决方案1】:

你可以在这里使用$filter聚合

db.collection.aggregate([
  { "$addFields": {
    "e": {
      "$filter": {
        "input": "$e"
        "cond": { "$eq": ["$$this.isDeleted", true] }
      }
    }
  }}
])

【讨论】:

  • 太棒了!我花了一段时间才用 C# 来表达这一点(这有点复杂,因为我的实际场景是属性DateTime? DeletedAt,而不是简单的bool),但我似乎最终让它工作了。只是为了确保我们在同一页面上:本质上我们正在用过滤器的结果覆盖e 集合,对吗?你知道这是否是一个危险信号还是我希望的优化?
  • 这种方法使用聚合——当你首先进行更新时也可以使用它吗?即我有两条路径:一条获取数据,一条更新数据。更新路径会在更新后返回修改后的文档。我可以将聚合应用于纯“读取”路径,但“更新”路径似乎混合了两种不兼容的方法。
  • 带有过滤器结果的集合,对吗? 是的。那么$addFields$project 对性能没有影响,两者都会以相同的效率为您提供相同的结果。 这也可以在您先进行更新时使用吗? 我认为您不能。更新和聚合都是不同的函数/查询,工作方式也不同。
  • 这很公平。你能想出一种适用于更新命令的替代方法吗?
  • 我总是为这种类型的操作调用多个 api,而不是做同样的事情。由于 mongodb 是可扩展的数据库,因此执行此类操作总是很容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2021-07-15
  • 1970-01-01
  • 2014-01-09
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多