我有一系列像这样的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}
]
}
]
);
我想在上面的数组中找到包含仅“成员”ID的集合“组”中的所有文档,并且的顺序不应该。例如,如果使用上述数组进行搜索,则仅将从上方返回第二个插入的文档。
答案 0 :(得分:1)
您需要使用MongoDB's aggregation pipeline来查找所需的文档。
汇总中采用的步骤如下:
通过解构members
数组来对每个文档进行非规范化。
这可以通过使用$unwind来实现 聚合运算符:
从输入文档解构数组字段,为每个元素输出文档。每个输出文档都是输入文档,数组字段的值由元素替换。
$unwind
运算符会将每个文档拆分为多个文档,每个新文档都包含一个members
字段,该字段包含一个成员对象:
{_id: 'first_id', members: {member: 4, hasSeen: false}}
{_id: 'first_id', members: {member: 5, hasSeen: fasee}}
要使用$unwind
运算符,我们只需将其添加到聚合管道:
{$unwind: "$members"}
按照_id
字段对文档进行分组,将成员ID添加到数组
这可以通过使用$group聚合运算符来实现:
按一些指定的表达式对文档进行分组,并为每个不同的分组输出到下一个阶段的文档。输出文档包含一个_id字段,该字段按键包含不同的组。输出文档还可以包含计算字段,这些字段包含按$ group的_id字段分组的某些累加器表达式的值。
$group
运算符允许我们在累积成员ID时通过其ID对非规范化文档进行分组,以便我们获取此表单的文档:
{_id: 'first_id', member_ids: [5, 7, 4] }
对文档进行分组并累积ID所需的表达式为:
{$group: { _id: "$_id", member_ids: { $push: "$members.member" } }}
根据定义的条件过滤生成的文档
这可以通过使用$match聚合运算符来实现:
过滤文档以仅将符合指定条件的文档传递到下一个管道阶段。
要获取member_ids
属性与条件匹配的文档,表达式为:
{$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] } } }
]
);