gpt4 book ai didi

node.js - 使用 $redact 过滤多个数组

转载 作者:太空宇宙 更新时间:2023-11-04 02:15:15 27 4
gpt4 key购买 nike

我实际上正在尝试发出一个 mongodb 请求,首先在一个列表上填充过滤器,然后在另一个列表上填充过滤器。

说明

我的数据库中有以下对象:

{
"_id": ObjectId("..."),
"title": "MySuperProject",
"files": [
{
"title":"My skiing day !",
"right":[{
"role":"USER",
"access":["read"]
}]
},
{
"title":"My little dog, so cute !",
"right":[{
"role":"OTHER",
"access":["read"]
}]
}
],

"people": [
{
"userName":"borat",
"role":"OTHERONE",
"right":[{
"role":"USER",
"access":["read"]
}]
},
{
"userName":"Thomas",
"role":"OTHER",
"right":[{
"role":"OTHER",
"access":["read"]
}]
}
]
}

我需要什么

我需要将一个参数传递给我的函数,该参数是当前用户角色。就我而言,我传递了“USER”角色。

这样,我需要检索这个结果:

{
"_id": ObjectId("..."),
"title": "MySuperProject",
"files": [
{
"title":"My skiing day !",
"right":[{
"role":"USER",
"access":["read"]
}]
}
],

"people": [
{
"userName":"borat",
"role":"OTHER",
"right":[{
"role":"USER",
"access":["read"]
}]
}
]
}

这会减少与我的项目角色匹配的两个列表。

我有什么

我有一个查询,可以通过“角色”属性减少文件列表。

事实是,在我的人员列表中,我有两次角色属性:

  • 一次确定人员角色
  • 一次确定哪些人可以访问(正确访问)人员个人资料

我的查询通过匹配遇到的第一个角色(people.role 而不是 people.right.role)来减少人员结果集。

我的查询如下:

db.t.aggregate([
{
$match: {
"title": projectTitle
}
},
{
$redact: {
$cond: [{
$eq: [role, {
$ifNull: ["$role", role]
}]
}, "$$DESCEND", "$$PRUNE"]
}
},
{
$redact: {
$cond: [{
$gt: [{
$size: {
$ifNull: ["$right", [1]]
}
}, 0]
}, "$$DESCEND", "$$PRUNE"]
}
},
])

总结:我需要查询减少与 right.role 值匹配的人员和文件列表

最佳答案

$redact管道阶段并不是最好的工具,因为它不能很好地转换为“不同级别的不同条件”,也不能根据其预期功能的性质很好地转换为“以不同方式处理不同的数组”。

这里更好的情况是普通的旧数组过滤,有一段时间已经有一些方法了。

最好的选择是 $filter从 MongoDB 3.2 开始,如果你有:

db.t.aggregate([
{ "$project": {
"title": 1,
"files": {
"$filter": {
"input": "$files",
"as": "file",
"cond": { "$eq": [ "$$file.right.role", "USER" ] }
}
},
"people": {
"$filter": {
"input": "$people",
"as": "person",
"cond": { "$eq": [ "$$person.right.role", "USER" ] }
}
}
}}
])

对于 MongoDB 2.6,如果您的数组元素确实“不同”并且文档中没有两个元素相同,那么您可以使用 $map “模拟”该新函数。和 $setDifference从数组中删除任何 false 结果:

db.t.aggregate([
{ "$project": {
"title": 1,
"files": {
"$setDifference": [
{ "$map": {
"input": "$files",
"as": "file",
"in": {
"$cond": [
{ "$eq": [ "$$file.right.role", "USER" ] },
"$$file",
false
]
}
}},
[false]
]
},
"people": {
"$setDifference": [
{ "$map": {
"input": "$people",
"as": "person",
"in": {
"$cond": [
{ "$eq": [ "$$person.right.role", "USER" ] },
"$$person",
false
]
}
}},
[false]
]
}
}}
])

这是相同的基本条件测试,除了在后一种情况下 $map 仅返回作为输入提供的每个数组元素的一个元素。因此,要么是匹配的元素,要么是 false 值,然后通过与 $setDifference 中的 false 进行“设置比较”将其删除。

这些都是单管道阶段操作,因此它们是执行此操作的最快方法。

一如既往,除非您确实需要此信息进入进一步的聚合管道阶段,或者您确实将数组中的内容减少了“大量”以节省大量网络流量,否则最好在客户端中对数据库本身进行这种“过滤”。

这些过程都不会真正产生太多开销,但客户端代码可以说是直接的,并且从“一点”较少的网络流量中获得的东西可能会损失在服务器上的处理成本中。

关于node.js - 使用 $redact 过滤多个数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36056254/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com