MongoDB聚合查询中如何仅投影数组内匹配的元素
解决MongoDB聚合中仅投影数组内匹配条件元素的问题
你当前的问题是在聚合投影阶段无法只返回searchKeys数组中符合查询条件的元素,原因是$elemMatch属于查询阶段运算符,不能在$project阶段使用。正确的做法是使用聚合数组运算符$filter来筛选数组元素。
修改后的完整聚合查询
db.collection.aggregate([ { $match: { buyerId: "10", $or: [ { "searchKeys.value": { $regex: "company", $options: "i" } }, { "searchKeys.valueClean": { $regex: "company", $options: "i" } } ] } }, { $project: { companyId: 1, buyerId: 1, companyName: 1, legalForm: 1, country: 1, vat: 1, erpCode: 1, searchKeys: { $filter: { input: "$searchKeys", cond: { $or: [ { $regexMatch: { input: "$$this.value", regex: "company", options: "i" } }, { $regexMatch: { input: "$$this.valueClean", regex: "company", options: "i" } } ] } } } } } ])
关键说明
$filter的使用:这是聚合阶段专门用于数组筛选的运算符,通过input指定要处理的数组,cond定义筛选条件,最终返回满足条件的数组元素。$$this的含义:代表数组当前遍历到的元素,通过它可以访问每个子对象的value和valueClean字段。- 正则匹配的聚合写法:使用
$regexMatch聚合运算符实现正则匹配,替代查询阶段的$regex,确保在投影阶段可以执行正则判断。 - 类型匹配修正:原数据中
buyerId是字符串类型"10",注意和查询条件中的类型保持一致,避免匹配失败。
兼容低版本MongoDB(<4.2)的写法
如果你的MongoDB版本不支持$regexMatch,可以用$indexOfCP结合$toLower实现不区分大小写的匹配:
db.collection.aggregate([ { $match: { buyerId: "10", $or: [ { "searchKeys.value": { $regex: "company", $options: "i" } }, { "searchKeys.valueClean": { $regex: "company", $options: "i" } } ] } }, { $project: { companyId: 1, buyerId: 1, companyName: 1, legalForm: 1, country: 1, vat: 1, erpCode: 1, searchKeys: { $filter: { input: "$searchKeys", cond: { $or: [ { $ne: [ { $indexOfCP: [ { $toLower: "$$this.value" }, "company" ] }, -1 ] }, { $ne: [ { $indexOfCP: [ { $toLower: "$$this.valueClean" }, "company" ] }, -1 ] } ] } } } } } ])
内容的提问来源于stack exchange,提问作者Luca Riccitelli
相关产品推荐
相关产品推荐

