查找某些字段与MongoDB和Node.js中的对象具有完全相同元素的文档
我有一个像这样的ID数组:
[5, 7, 9, 4, 18]
我有一个与以下格式插入文档的集合:
db.collection('groups').insert( [ { members: [ {member: 5, hasSeen: false, requiresAction: true}, {member: 7, hasSeen: true, requiresAction: true}, {member: 4, hasSeen: false, requiresAction: false} ] }, { members: [ {member: 5, hasSeen: false, requiresAction: true}, {member: 4, hasSeen: false, requiresAction: false}, {member: 7, hasSeen: true, requiresAction: true}, {member: 9, hasSeen: false, requiresAction: false}, {member: 18, hasSeen: false, requiresAction: false} ] }, { members: [ {member: 7, hasSeen: true, requiresAction: true}, {member: 9, hasSeen: false, requiresAction: false}, {member: 4, hasSeen: false, requiresAction: false}, {member: 18, hasSeen: false, requiresAction: false}, {member: 1, hasSeen: false, requiresAction: false}, {member: 5, hasSeen: false, requiresAction: true} ] } ] );
我想查找集合“组”中的所有文档,其中只包含上述数组中的“成员”标识,顺序应该没有关系。 例如,如果使用上述数组进行search,则只有第二个插入的文档将从上面返回。
您需要使用MongoDB的聚合pipe道来查找所需的文档。
下面列出了在聚合中采用的步骤:
-
通过解构
members
数组来反规范化每个文档。这可以通过使用$ unwind聚合运算符来实现:
从input文档中解构一个数组字段,为每个元素输出一个文档。 每个输出文档都是由元素replace的数组字段值的input文档。
$unwind
操作符会将每个文档分成几个文档,每个新文档包含一个具有单个成员对象的members
字段:{_id: 'first_id', members: {member: 4, hasSeen: false}} {_id: 'first_id', members: {member: 5, hasSeen: fasee}}
要使用
$unwind
运算符,我们只需将其添加到聚合pipe道:{$unwind: "$members"}
-
通过
_id
字段对文档进行分组,将成员标识添加到数组中这可以通过使用$ group聚合运算符来实现:
按照某个指定的expression式对文档进行分组,并将每个不同分组的文档输出到下一个阶段。 输出文档包含一个_id字段,其中包含按键的不同组。 输出文档还可以包含计算字段,该字段包含由$ group的_id字段分组的一些累加器expression式的值。
$group
操作符将允许我们通过它们的id将非规范化文档分组,所以我们将获得这种forms的文档:{_id: 'first_id', member_ids: [5, 7, 4] }
将文档分组和汇总ID所需的expression式是:
{$group: { _id: "$_id", member_ids: { $push: "$members.member" } }}
-
根据定义的标准过滤结果文档
这可以通过使用$ match聚合运算符来实现:
过滤文档以仅将符合指定条件的文档传递到下一个stream水线阶段。
要获取其
member_ids
属性与条件匹配的文档,expression式为:{$match: {'member_ids': { $all: [5, 7, 9, 4, 18] } } }
最后的聚合查询将是:
db.collection('groups').aggregate( [ {$unwind: "$members"}, {$group: { _id: "$_id", member_ids: { $push: "$members.member" } }}, {$match: {'member_ids': { $all: [5, 7, 9, 4, 18] } } } ] );