如何查询子数组中的条目与所有条件匹配的文档?

Posted

技术标签:

【中文标题】如何查询子数组中的条目与所有条件匹配的文档?【英文标题】:How do I query documents where an entry in a sub-array matches all conditions? 【发布时间】:2017-07-21 23:46:31 【问题描述】:

以下是我的角色和职责收集文件

[
    "_id": 
        "$oid": "58b6c380734d1d48176c9e69"
    ,
    "role": "Admin",
    "resource": [
        
            "id": "blog",
            "permissions": [
                "read",
                "update",
                "delete"
            ]
        ,
        
            "id": "user",
            "permissions": [
                "create",
                "read",
                "update",
                "delete"
            ]
        ,
        
            "id": "journal",
            "permissions": [
                "create",
                "read",
                "update",
                "delete"
            ]
        
    ]
,

    "_id": 
        "$oid": "58b7db3cf36d285019ea175f"
    ,
    "role": "Manager",
    "resource": [
        
            "id": "blog",
            "permissions": [
                "read",
                "update",
                "delete"
            ]
        ,
        
            "id": "user",
            "permissions": [
                "create",
                "read",
                "update",
                "delete"
            ]
        ,
        
            "id": "journal",
            "permissions": [
                "create",
                "read",
                "update",
                "delete"
            ]
        
    ]
]

我想检查管理员是否有创建权限。 我写过这样的查询

var check =  $and: [  'role':req.body.role, ,   'resource.id':'blog','resource.permissions':'create' ] 
Rolesandresponsibilitie.find(check).populate('user', 'displayName').exec(function(err, rolesandresponsibilities) 
        if (err) return next(err);
        if (! rolesandresponsibilities) return res.status(404).send('Not Found'); ;
        return res.status(200).send('Found'); 

    );

我越来越不确定

我的期望:

例如1:

角色 = 管理员

id = 博客

权限 = 创建

我应该得到响应 Not Found 因为管理员只有

“权限”:[ “读”, “更新”, “删除” ]

3 个以上权限

示例 2:

角色 = 管理员

id = 博客

权限 = 读取

我应该得到响应,因为管理员具有读取权限

【问题讨论】:

【参考方案1】:

如果要在子文档数组中查询,并且要根据每个子文档放置条件,则需要使用 $elemMatch。

var check =  $and: [  'role':req.body.role, ,   resource:  $elemMatch:  'id': 'blog', 'permissions': 'create'     ] 

如上所述更改条件。

【讨论】:

【参考方案2】:

$elemMatch 是您所需要的,它将简化查询。 默认情况下,mongo 会将查询中的属性视为 $and 语句,因此无需在此处添加。

一个更简单的查询是

var check = 
    'role':req.body.role,
    'resource':
        '$elemMatch': 
            'id': 'blog',
            'permissions': 'create'
        
     


Rolesandresponsibilitie.find(check).populate('user', 'displayName').exec(function(err, rolesandresponsibilities) 
    if (err) return next(err);
    if (! rolesandresponsibilities) return res.status(404).send('Not Found'); ;
    return res.status(200).send('Found'); 

);

您当前遇到的问题是因为查询

'resource.id':blog and 'resource.permissions':create

是您在数组中有匹配两个过滤器的元素。 它只是简单地检查资源数组以判断是否有 id=blog 以及是否有权限=create,结果不一定是数组中的相同条目。

祝你好运!

【讨论】:

没问题,我刚开始使用 mongodb 时遇到了这个问题。很高兴你觉得它有帮助 ***.com/questions/43501008/….help

以上是关于如何查询子数组中的条目与所有条件匹配的文档?的主要内容,如果未能解决你的问题,请参考以下文章

如何编写查询来检索每个匹配的子文档数组

如何匹配 MongoDB 中的子文档数组?

如何匹配MongoDB中的子文档数组?

在 Mongoose/MongoDB 的文档中过滤数组、子文档、数组、文档

如何使用 apollo 缓存来匹配作为子数组/子 ID 列表的输入变量?

MongoDB - 仅当嵌套数组中的所有条目存在时才更新它们