db.col.aggregate([
{
$match: {
field_nest: { $elemMatch: { /* conditions */ } }
}
}
])
这是我当前的设置。除了匹配父文档之外,它还需要只返回与$elemMatch
匹配的子文档。
否则,我将不得不再次使用$unwind
和$match
。但这将不再能够使用索引。我们的想法是能够使用索引。
不,$match
阶段选择文档沿着管道传递,它不修改正在传递的文档。
您可以在$match
阶段使用$elemMatch
来选择文档,然后在$addFields
阶段使用$filter
来过滤掉不匹配的元素。
可能是这样的:
db.col.aggregate([
{$match: {
field_nest: { $elemMatch: { /* conditions */ } }
}},
{$addFields: {
field_nest: {$filter:{
input: "$field_nest",
as: "item",
cond: { /* conditions */ }
}}
}}
])
根据确切的条件和可用的索引,可以使用索引。
例如,如果查询为
db.col.aggregate([
{$match: {
field_nest:{$elemMatch:{a:1,b:2}}
}}
])
可以在{"field_nest.a":1,"field_nest.b":1}
上使用索引,但不能在{field_nest:1}
或{"field_next.c":1, "field_next.a":1}
上使用索引。
如果查询是
db.col.aggregate([
{$match: {
top_field: "name",
some_value: {$gte: "never"},
field_nest:{$elemMatch:{a:1,b:2}}
}}
])
查询执行程序将查看所有可用的索引,但可能使用不包含数组字段的索引。
如果查询是
{$match: {
top_field: "name",
some_value: {$gte: "never"},
field_nest:{$elemMatch:{a:{$regex:"unanchored"},b:2}}
}}
])
它将不能使用索引来选择field_nest.a
,但可以使用索引来选择field_nest.b
。
是否使用索引在很大程度上取决于匹配条件和可用索引的确切性质。