是否有一种方法来过滤$match阶段的子文档数组?


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

是否使用索引在很大程度上取决于匹配条件和可用索引的确切性质。

最新更新