我试图使用CASL对嵌套项进行授权检查。它使用猫鼬来查询数据和检查访问。
我的领域是:
模式:
vehicle { users: [ {type: objectId, ref: 'user'} ] }
document { vehicle: {type: objectId, ref: 'vehicle' }}若要“按用户”查找车辆,我会:
db.getCollection('vehicle').find(
{ users: {$in: [ ObjectId("5ae1a957d67500018efa2c9d") ]} }
)这是可行的。
在文件收集中,数据具有如下记录:
{
"_id": ObjectId("5aeaad1277e8a6009842564d"),
"vehicle": ObjectId("5aea338b82d8170096b52ce9"),
"company": "Allianz",
"price": 500,
"date_start": ISODate("2018-05-02T22:00:00.000Z"),
"date_end": ISODate("2019-05-02T22:00:00.000Z"),
"createdAt": ISODate("2018-05-03T06:32:50.590Z"),
"updatedAt": ISODate("2018-05-03T06:32:50.590Z"),
"__v": 0
}要查找“用户”文档,我需要:
db.getCollection('document').find(
{ "vehicle.users": {$in: [ ObjectId("5ae1a957d67500018efa2c9d") ]} }
)它不起作用。是否有可能在一个单一的“查找”查询中做到这一点?
发布于 2018-05-03 18:18:41
您不能在简单的MongoDB 查找()查询中这样做,因为有关车辆用户的数据存在于车辆集合中,而不是文档集合中。
但是,使用聚集管线可以使用$lookup操作符将数据链接到两个不同的集合中。聚合应该是这样的:
db.document.aggregate([
{$lookup: {
"from": "vehicle",
"localField": "vehicle",
"foreignField": "_id",
"as": "vehicleDetails",
}},
{$match: {"vehicleDetails.users" : ObjectId("5ae1a957d67500018efa2c9d")}}
])您可能需要添加更多的阶段来按照您需要的方式重新构造数据,但关键是使用$lookup链接来自两个集合的数据,然后使用$match过滤结果集。
发布于 2018-06-05 10:52:44
为了使此查询工作,需要将users In数组存储在vehicle文档中。Mongo和CASL都不会自动管理外部引用。
替代解决方案
所以,我看不出什么方法:
const vehicleIds = await getVehicleIds(user)
can(['read', 'update'], 'document', { vehicle: { $in: vehicleIds } })user_id字段添加到车辆文档中vehicle {
documents: [Document],
users: [ {type: objectId, ref: 'user'} ]
}app.get('/vehicle/:id/documents', async (req, res) => {
const vehicle = await Vehicle.findById(req.params.id)
req.ability.throwUnlessCan('read', vehicle)
const documents = Document.find({ vehicle: vehicle.id })
res.send({ documents })
})https://stackoverflow.com/questions/50154241
复制相似问题