MongoDB聚合中如何获取数组匹配指定值的所有索引?$indexOfArray仅返回首个
在MongoDB聚合中获取数组所有匹配值的索引
$indexOfArray 只能返回数组中第一个匹配目标值的索引,要获取所有匹配项的索引,可以通过生成索引范围+筛选匹配项的组合操作实现,以下是具体方案:
示例文档
{ data: [-1, 100, 150, 200, -1, -1] }
聚合管道实现
db.collection.aggregate([ // 生成与data数组长度一致的索引数组(0到n-1) { $addFields: { indices: { $range: [0, { $size: "$data" }] } } }, // 筛选出data中对应索引值等于目标值的索引 { $addFields: { matchingIndices: { $filter: { input: "$indices", as: "idx", cond: { $eq: [{ $arrayElemAt: ["$data", "$$idx"] }, -1] } } } } }, // 清理临时字段,保留结果 { $project: { _id: 0, data: 1, matchingIndices: 1 } } ])
执行结果
{ "data": [-1, 100, 150, 200, -1, -1], "matchingIndices": [0, 4, 5] }
关键步骤说明
- 生成索引范围:用
$range生成从0到数组长度-1的连续整数数组,对应data每个元素的索引位置。 - 筛选匹配索引:通过
$filter遍历索引数组,对每个索引$$idx,用$arrayElemAt取出data中对应位置的元素,判断是否等于目标值(这里是-1),符合条件的索引会被保留到matchingIndices数组中。 - 清理字段:可选的
$project阶段用于移除临时生成的indices字段,只保留需要的结果字段。
动态指定匹配值
如果需要动态传入目标值,可以在聚合中定义变量或直接替换目标值:
db.collection.aggregate([ { $addFields: { targetValue: -1, // 此处可替换为动态参数 indices: { $range: [0, { $size: "$data" }] } } }, { $addFields: { matchingIndices: { $filter: { input: "$indices", as: "idx", cond: { $eq: [{ $arrayElemAt: ["$data", "$$idx"] }, "$targetValue"] } } } } }, { $project: { _id: 0, data: 1, matchingIndices: 1 } } ])
内容的提问来源于stack exchange,提问作者jgwl
相关产品推荐
相关产品推荐

