嵌套过滤器:$filter 数组,然后是 $filter 子数组

2024-05-05

本质上,我试图过滤掉已被“废弃”的子文档和子子文档。这是我的架构的精简版本:

permitSchema = {
  _id,
  name,
  ...
  feeClassifications: [
    new Schema({
      _id,
      _trashed,
      name,
      fees: [
        new Schema({
          _id,
          _trashed,
          name,
          amount
        })
      ]
    })
  ],
  ...
}

这样我就能得到我想要的效果feeClassifications。但我正在努力寻找一种方法来达到同样的效果feeClassifications.fees以及。

所以,这按预期工作:

Permit.aggregate([
  { $match: { _id: mongoose.Types.ObjectId(req.params.id) }},
  { $project: {
    _id: 1,
    _name: 1,
    feeClassifications: {
      $filter: {
        input: '$feeClassifications',
        as: 'item',
        cond: { $not: {$gt: ['$$item._trashed', null] } }
      }
    }
  }}
])

但我也想过滤嵌套数组fees。我尝试过一些事情,包括:

Permit.aggregate([
  { $match: { _id: mongoose.Types.ObjectId(req.params.id) }},
  { $project: {
    _id: 1,
    _name: 1,
    feeClassifications: {
      $filter: {
        input: '$feeClassifications',
        as: 'item',
        cond: { $not: {$gt: ['$$item._trashed', null] } }
      },
      fees: {
        $filter: {
          input: '$fees',
          as: 'fee',
          cond: { $not: {$gt: ['$$fee._trashed', null] } }
        }
      }
    }
  }}
])

这似乎遵循mongodb 文档 https://docs.mongodb.com/manual/reference/operator/aggregation/project/最近的。但我收到错误:this object is already an operator expression, and can't be used as a document expression (at 'fees')

更新: - - - - - -

根据要求,这是一个示例文档:

{
    "_id" : ObjectId("57803fcd982971e403e3e879"),
    "_updated" : ISODate("2016-07-11T19:24:27.204Z"),
    "_created" : ISODate("2016-07-09T00:05:33.274Z"),
    "name" : "Single Event",
    "feeClassifications" : [ 
        {
            "_updated" : ISODate("2016-07-11T19:05:52.418Z"),
            "_created" : ISODate("2016-07-11T17:49:12.247Z"),
            "name" : "Event Type 1",
            "_id" : ObjectId("5783dc18e09be99840fad29f"),
            "fees" : [ 
                {
                    "_updated" : ISODate("2016-07-11T18:51:10.259Z"),
                    "_created" : ISODate("2016-07-11T18:41:16.110Z"),
                    "name" : "Basic Fee",
                    "amount" : 156.5,
                    "_id" : ObjectId("5783e84cc46a883349bb2339")
                }, 
                {
                    "_updated" : ISODate("2016-07-11T19:05:52.419Z"),
                    "_created" : ISODate("2016-07-11T19:05:47.340Z"),
                    "name" : "Secondary Fee",
                    "amount" : 50,
                    "_id" : ObjectId("5783ee0bad7bf8774f6f9b5f"),
                    "_trashed" : ISODate("2016-07-11T19:05:52.410Z")
                }
            ]
        }, 
        {
            "_updated" : ISODate("2016-07-11T18:22:21.567Z"),
            "_created" : ISODate("2016-07-11T18:22:21.567Z"),
            "name" : "Event Type 2",
            "_id" : ObjectId("5783e3dd540078de45bbbfaf"),
            "_trashed" : ISODate("2016-07-11T19:24:27.203Z")
        }
    ]
}

这是所需的输出(“废弃”子文档均被排除在外)feeClassifications AND fees):

{
    "_id" : ObjectId("57803fcd982971e403e3e879"),
    "_updated" : ISODate("2016-07-11T19:24:27.204Z"),
    "_created" : ISODate("2016-07-09T00:05:33.274Z"),
    "name" : "Single Event",
    "feeClassifications" : [ 
        {
            "_updated" : ISODate("2016-07-11T19:05:52.418Z"),
            "_created" : ISODate("2016-07-11T17:49:12.247Z"),
            "name" : "Event Type 1",
            "_id" : ObjectId("5783dc18e09be99840fad29f"),
            "fees" : [ 
                {
                    "_updated" : ISODate("2016-07-11T18:51:10.259Z"),
                    "_created" : ISODate("2016-07-11T18:41:16.110Z"),
                    "name" : "Basic Fee",
                    "amount" : 156.5,
                    "_id" : ObjectId("5783e84cc46a883349bb2339")
                }
            ]
        }
    ]
}

由于我们想要过滤外部和内部数组字段,因此我们可以使用$map https://docs.mongodb.com/manual/reference/operator/aggregation/map/变量运算符返回一个包含我们想要的“值”的数组。

In the $map表达式,我们提供了一个逻辑$cond https://docs.mongodb.com/manual/reference/operator/aggregation/conditional $filter https://docs.mongodb.com/manual/reference/operator/aggregation/filter从文档和子文档数组字段中删除不匹配的文档。

条件是$lt https://docs.mongodb.com/manual/reference/operator/aggregation/lt当子文档和/或子文档数组字段中不存在“_trashed”字段时,返回 true。

请注意,在$cond表达式我们也返回 false<false case>。当然我们需要应用过滤器$map结果删除全部false.

Permit.aggregate(
    [ 
        { "$match": { "_id": mongoose.Types.ObjectId(req.params.id) } },
        { "$project": { 
            "_updated": 1, 
            "_created": 1, 
            "name": 1, 
            "feeClassifications": { 
                "$filter": {
                    "input": {
                        "$map": { 
                            "input": "$feeClassifications", 
                            "as": "fclass", 
                            "in": { 
                                "$cond": [ 
                                    { "$lt": [ "$$fclass._trashed", 0 ] }, 
                                    { 
                                        "_updated": "$$fclass._updated", 
                                        "_created": "$$fclass._created", 
                                        "name": "$$fclass.name", 
                                        "_id": "$$fclass._id", 
                                        "fees": { 
                                            "$filter": { 
                                                "input": "$$fclass.fees", 
                                                "as": "fees", 
                                                "cond": { "$lt": [ "$$fees._trashed", 0 ] }
                                            }
                                        }
                                    }, 
                                    false 
                                ]
                            }
                        }
                    }, 
                    "as": "cls",  
                    "cond": "$$cls"
                }
            }
        }}
    ]
)

在即将发布的 MongoDB 版本中(截至撰写本文时以及自 MongoDB 3.3.5 起),您可以替换$cond表达在$map表达与$switch表达:

Permit.aggregate(
    [ 
        { "$match": { "_id": mongoose.Types.ObjectId(req.params.id) } },
        { "$project": { 
            "_updated": 1, 
            "_created": 1, 
            "name": 1, 
            "feeClassifications": { 
                "$filter": {
                    "input": {
                        "$map": { 
                            "input": "$feeClassifications", 
                            "as": "fclass", 
                            "in": { 
                                "$switch": { 
                                    "branches": [ 
                                        { 
                                            "case": { "$lt": [ "$$fclass._trashed", 0 ] }, 
                                            "then": { 
                                                "_updated": "$$fclass._updated", 
                                                "_created": "$$fclass._created", 
                                                "name": "$$fclass.name", 
                                                "_id": "$$fclass._id", 
                                                "fees": { 
                                                    "$filter": { 
                                                        "input": "$$fclass.fees", 
                                                        "as": "fees", 
                                                        "cond": { "$lt": [ "$$fees._trashed", 0 ] }
                                                    }
                                                }
                                            } 
                                        } 
                                    ], 
                                    "default":  false 
                                }
                            }
                        }
                    },
                    "as": "cls",  
                    "cond": "$$cls"
                }
            }
        }}
    ]
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌套过滤器:$filter 数组,然后是 $filter 子数组 的相关文章

随机推荐

  • 使用 openCV 和 python 检测物体

    我正在尝试使用 OpenCV 和 Python 检测下图中的白点 我尝试使用函数 cv2 HoughCircles 但没有成功 我需要使用不同的方法吗 这是我的代码 import cv2 cv import numpy as np impo
  • 使用多个 DispatchQueue.main.async 查看冻结

    视图冻结而数据是获取并显示 以我的理解fetchBoard and initUserInfo 不要并行执行 因为视图仅在以下情况下加载fetchBoard 加载板 我担心如果使用DispatchQueue main async多次冻结视图
  • Java - Servlet 的默认 contentType

    在servlet中 通常我们会指定一个contentType 然后我们就可以打印出html代码了 response setContentType text html PrintWriter out response getWriter 如果
  • IMAP CONDSTORE 是否得到广泛支持?

    我正在构建一个简单的网络邮件 我想使用 IMAP 的 CONDSTORE 扩展 它允许获取自某个日期以来已更改的所有内容 消息 标志等 这对于将电子邮件客户端同步到IMAP 服务器 但是我完全不知道大多数 IMAP 服务器是否真正支持此 I
  • ASP MVC4 - 通过视图模型传递列表以查看

    我有一个模型人物 其中包括出生日期等字段 我想将所有人的列表以及每个人的计算年龄传递给视图 因此 视图模型 public class vm PersonList public Person Person get set public int
  • 在没有事件的情况下从 HTML 执行 javascript 函数

    我希望从 HTML 页面调用 javascript 函数 并且我do not希望它依赖于任何事件 该函数位于单独的 js 文件中 因为我希望在许多网页中使用它 我也将变量传递给它 我试过这个 HTML fp footer2 js中的函数 f
  • 检查远程计算机上的进程所有者,并在所有者为 xyz 时将其终止

    嘿 我想在远程计算机上检查特定进程的进程所有者 并在所有者是 xyz 时杀死它 我已经成功地检查了它的主人 但我不知道当主人是 xyz 时如何杀死它 到目前为止我所拥有的 get wmiobject computername remoteP
  • PreferenceActivity 如何使用自定义首选项文件

    我第一次尝试偏好是在不了解PreferenceActivity 所以现在我有一个应用程序将所有用户首选项存储在特定的首选项文件中 我想迁移到使用 PreferenceActivity 但我也希望我的用户保留他们的偏好 有没有办法告诉我的 P
  • 如何使用 diff 排除多行模式?

    我想对两个 xml 文件进行比较 但忽略 2 3 行模式 例如 假设我想在比较下面的 xml 格式时忽略可用性和价格 这是我到目前为止所拥有的 diff I
  • 是否有与 SQL Server newsequentialid() 等效的 .NET

    我们使用 GUID 作为主键 您知道默认情况下它是集群的 将新行插入表中时 它将插入表中的随机页 因为 GUID 是随机的 这会对性能产生可衡量的影响 因为数据库始终会分割数据页 碎片 但我使用顺序 GUID 的主要原因是因为我希望将新行插
  • jQuery AJAX 或 XHR 请求从完成回调触发失败回调

    在我的 jQuery XHR 的完成处理程序 从 get 调用创建 中是否有一种方法可以查找响应中的问题 然后使用自定义错误消息触发注册的后续处理程序 即失败和始终 像这样的东西 get URL done function data sta
  • Gem .gemspec 中的本地依赖关系

    我正在开发一个 gem Gem A 它使用了我也编写的另一个 gem Gem B 到目前为止 Gem B 已添加到 Gem A 的 gemspec 中 gem add dependency gem a gt 0 0 4 但我现在发现需要使用
  • 在闪亮的应用程序中选择文件夹或文件夹目录

    我在使用闪亮时遇到问题 我想选择保存我要在应用程序中使用的所有文件的文件夹 方法是 1 将工作目录设置为该文件夹路径 或 2 将此文件夹内的所有 csv 数据上传到我的应用程序以进行进一步处理 1 我找到了shinyFiles包 但它非常非
  • 在 (PHP/GD) 中调整图像大小

    我正在寻找帮助 建议 以找到最有效的方法来使用以下方法将图像大小调整为尽可能小PHP GD同时保留原始图像的纵横比 但确保调整后的图像大于定义的最小宽度和高度 例如 调整大小后的图像必须具有宽度 gt 400 且高度 gt 300但应尽可能
  • FirebaseIndexRecyclerAdapter onDataChanged 被调用但 getItemCount() 始终返回 0

    我在用着FirebaseIndexRecyclerAdapter https github com firebase FirebaseUI Android blob master database src main java com fir
  • lambda 始终返回“1”

    有这样的代码 include
  • 如何根据 URL 路径添加 CSS 类?

    如何根据我所在的路径将 CSS 类添加到 div 中 包括如果我在其中包含 则不应该出现问题 div class popup ul li a href vs Example 1 a li li a href bod Example 2 a
  • xcodebuild 失败,返回代码:65 - 使用 CLI/Appcenter 但没有错误消息

    我已将 React Native 应用程序升级到 0 59 现在当我尝试使用 AppCenter 或 CLI 存档我的应 用程序时 我收到错误代码 65 但没有任何消息解释问题 当我直接从 Xcode 构建时 Xcode版本 10 2 1
  • C++ 最大非负整数

    以下内容是否会在所有平台 int 大小等上按预期工作 或者有更容易接受的方法吗 我做了以下的事情 define MAX NON NEGATIVE INT int unsigned int 1 2 我不会通过解释它在做什么来侮辱你的智商 编辑
  • 嵌套过滤器:$filter 数组,然后是 $filter 子数组

    本质上 我试图过滤掉已被 废弃 的子文档和子子文档 这是我的架构的精简版本 permitSchema id name feeClassifications new Schema id trashed name fees new Schema