MongoDB获取需要与同一集合中的其他文档进行比较的唯一文档
下面是我在测试集合中的示例文档结构 问题描述: 我必须根据以下条件从本文档中获取MongoDB获取需要与同一集合中的其他文档进行比较的唯一文档,mongodb,mongodb-query,Mongodb,Mongodb Query,下面是我在测试集合中的示例文档结构 问题描述: 我必须根据以下条件从本文档中获取名称字段 我将通过角色字段作为查询条件。它应该获取与文档中的角色无关的名称值 请考虑下面的文档。如果我的查询标准是“角色 R1 < /Cord>”,则“查找查询”应将名称返回为: {“name”:“S”},{“name”:“G”},{“name”:“H”} 因为在集合中的任何文档中,r1未分配给此名称 同样的规则适用于所有角色,如r2,r3…r7。 因此,基本上我们必须查找集合中的所有文档,并且需要获取未分配给任何组
名称
字段
我将通过角色
字段作为查询条件。它应该获取与文档中的角色
无关的名称
值
请考虑下面的文档。如果我的查询标准是“角色<代码> R1 < /Cord>”,则“查找查询”应将名称返回为:
{“name”:“S”},{“name”:“G”},{“name”:“H”}
因为在集合中的任何文档中,r1
未分配给此名称
同样的规则适用于所有角色,如r2
,r3
…r7
。
因此,基本上我们必须查找集合中的所有文档,并且需要获取未分配给任何组的名称
/* 0 */
{
"_id" : ObjectId("567286bda5543ad892916a49"),
"name" : "A",
"role" : "r1"
}
/* 1 */
{
"_id" : ObjectId("567286bda5543ad892916a4a"),
"name" : "A",
"role" : "r2"
}
/* 2 */
{
"_id" : ObjectId("567286bda5543ad892916a4b"),
"name" : "A",
"role" : "r3"
}
/* 3 */
{
"_id" : ObjectId("567286bda5543ad892916a4c"),
"name" : "B",
"role" : "r2"
}
/* 4 */
{
"_id" : ObjectId("567286bda5543ad892916a4d"),
"name" : "A",
"role" : "r4"
}
/* 5 */
{
"_id" : ObjectId("567286bda5543ad892916a4e"),
"name" : "B",
"role" : "r1"
}
/* 6 */
{
"_id" : ObjectId("5672a8b7a5543ad892916a4f"),
"name" : "S",
"role" : "r3"
}
/* 7 */
{
"_id" : ObjectId("5672a8b7a5543ad892916a50"),
"name" : "G",
"role" : "r6"
}
/* 8 */
{
"_id" : ObjectId("5672a8b7a5543ad892916a51"),
"name" : "H",
"role" : "r2"
}
预期产出:
-- input is role `r1` then (Need to show the name if `r1` is not associate already) -- same description for all the roles
{"name" : "S"},
{"name" : "G"},
{"name" : "H"}
-- input is role 'r2' then
{"name" : "S"},
{"name" : "G"}
-- input is role 'r3' then
{"name" : "B"},
{"name" : "G"},
{"name" : "H"}
-- input is role 'r4' then
{"name" : "B"},
{"name" : "S"},
{"name" : "G"},
{"name" : "H"}
-- input is role 'r6' then
{"name" : "A"},
{"name" : "B"},
{"name" : "S"},
{"name" : "H"}
非常感谢您的帮助。如何实现这一点。
aggregation
framework还是普通的find查询?请给出建议。您可以尝试使用聚合:
db.getCollection('roles').aggregate([
{$group: {_id:"$name", "roles":{$addToSet:"$role"}}},
{$project: {_id:1, "roles": 1, "isSubset": { $setIsSubset: [ ["r1"], "$roles" ] }}},
{$match: {"isSubset": false}},
{$group: {_id:"$isSubset", "name": {$push : "$_id"}}},
{$project: {"_id": 0, "name": 1}},
{$unwind: "$name"}
])
roles
array”的子集我找到了一个比已经被接受的答案更好的方法来获得这个结果,我认为性能会更好。请查看:
db.collection.aggregate([
{
$group: { _id: null,
rightrole: { $addToSet: { $cond : {if: { $ne: [ "$role", "r1" ] }, then: "$name", else: null }} },
wrongrole: { $addToSet: { $cond : {if: { $eq: [ "$role", "r1" ] }, then: "$name", else: null } } } }
},
{ "$project": {"_id": 0,
"name": { "$setDifference": [ "$rightrole", "$wrongrole" ] } }
}, {$unwind: "$name"}
]);
请让我知道去那里的路done@Hecnanae:你太棒了。你让我开心了。工作得很好。非常感谢。如果我们使用此聚合,是否有任何性能命中率会上升?我不知道。它应该是在测试性能。我推荐这个。