mongodb - 查询 Mongodb 的文档,这些文档的子对象在关联数组中具有特定的 elem 值

标签 mongodb

棘手的 mongodb 查询问题:我有一个“帐户”集合,其中包含一堆文档(经过简化并将实际数据交换为非真实值)如下所示:

{"_id": "<Mongo Binary Data>",
 "Roles": {
     "D7753879C7020F8ECF947122FA211413": {
       "_id": "<Mongo Binary Data>",
       "OrgName": "ACME",
       "Rolename": "Coyote Liaison",
    },

     "CFA7722E6799170706E4C5FFF3F01E63": {
       "_id": "<Mongo Binary Data>",
       "OrgName": "ACME",      
       "Rolename": "MembershipAdmin",
    },

     "C7020F8ECF947122FAGIGHFVFF3F7753": {
       "_id": "<Mongo Binary Data>",
       "OrgName": "Initech",       
       "Rolename": "MembershipAdmin",
    }   
  } 
}

Roles 数组中的键是角色 ID 和组织 ID 的组合,然后对其进行哈希处理,这使得查询(一旦从 MongoDB 加载帐户对象并进入 C# 后)是否非常快速帐户具有给定组织的给定角色,即用户是 Initech 的 MembershipAdmin。

现在我想查询对任何组织都有角色的用户,在伪 SQL 中可以表示为“选择至少有一个角色对象的所有帐户,其中 Rolename = THISROLENAME”。即,获取所有属于 MembershipAdmins 的用户。

我试过这个:

{
  Roles.Rolename: "MembershipAdmin"
}

还有这个

{
  Roles: {"Rolename": "MembershipAdmin"}
}

还有这个

{
  Roles: {"$elemMatch": {"Rolename": "MembershipAdmin"}}
}

...无济于事,看到了几个答案,等等,说唯一的出路是将关联数组键向下推到子对象中,我不想这样做,因为它使主要该数据结构的功能(检查帐户是否具有给定组织的给定角色)确实非常快。我上面描述的用例不必非常快,因为它是管理员用户责任的一部分,所以我很乐意让他们等一会儿——所以在这种情况下,过度递归的查询等是可以的.

有没有人知道如何在不重构数据结构的情况下完成这项工作?对此我束手无策。

非常感谢,

G

[编辑:上面的结构是不可查询的,请参阅已接受的答案以获得博学但快速的解释,以了解为什么不可以以及您应该如何正确地修复它。但是,如果您对 hacky 解决方法没问题,您可以将数据的副本存储在 BsonArray 中,并使用 $elemMatch]

对其进行查询

最佳答案

没有办法用你想要的模式来做,也不是从一开始就非常实用的模式。您应该将架构更改为:

{"_id": "<Mongo Binary Data>",
 "Roles": [
    {
       "hash": "D7753879C7020F8ECF947122FA211413",
       "_id": "<Mongo Binary Data>",
       "OrgName": "ACME",
       "Rolename": "Coyote Liaison",
    },

    {
       "hash": "CFA7722E6799170706E4C5FFF3F01E63",
       "_id": "<Mongo Binary Data>",
       "OrgName": "ACME",      
       "Rolename": "MembershipAdmin",
    },

    {
       "hash": "C7020F8ECF947122FAGIGHFVFF3F7753",
       "_id": "<Mongo Binary Data>",
       "OrgName": "Initech",       
       "Rolename": "MembershipAdmin",
    }   
  ] 
}

之所以使用不稳定的值作为文档字段名称如此不切实际,正是因为它使大多数查询变得复杂。唯一的好处是某些查询可能会更快一些,但考虑到它也会导致索引问题,这几乎总是一个坏主意。

我强烈建议将您的模式更改为上述模式,而不是寻找允许您当前模式的解决方案。

编辑:正如在下面的讨论中提到的,在技术上可以使用 $where 运算符创建所需的查询。如果您不能以任何其他方式做到这一点,则意味着您有模式异味和潜在的扩展和性能瓶颈,当您的软件上线时,这些瓶颈将非常难以修复。不要在任何地方使用 $。曾经。

关于mongodb - 查询 Mongodb 的文档,这些文档的子对象在关联数组中具有特定的 elem 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11933901/

相关文章:

javascript - MEAN.JS 无法连接 MongoDB

mongodb - GoLang mgo - mgo.ErrNotFound for find(...).All(...)

php - 在 mongodb 中插入日期

java - 如何更新特定 mongoDB 集合的所有文档

mongodb组每2周

time - MongoDB ISO 日期()到。 UNIX 时间戳

mongodb - 在 pymongo 中使用 $or 子句

java - 使用java在mongodb中查找包含包含特定值的数组的文档

javascript - 我正在尝试使用 Ajax 捕获 facebook 数据并将其写入名为 test.txt 的文本文件

node.js - 跨多个模型导出和重用我的 Mongoose 连接