在MongoDB中使用JS函数与正则匹配字段统计符合条件的文档数量
MongoDB 同文档两字段前缀匹配统计方案
原有代码问题
- 正则写法错误:
/^x.field_2*/是静态正则,不会读取当前文档的field_2字段值,同时逻辑搞反:需求是field_2以field_1开头,不是field_1匹配field_2开头 - 嵌套查询逻辑冗余:不需要在
forEach内再次执行find,同文档字段直接对比即可,18万条数据嵌套查询会导致性能爆炸,无返回是因为执行时间过长
最优实现方案(推荐,18万数据秒出结果)
使用聚合操作直接在数据库层计算,通过截取field_2前两位和field_1直接对比,性能远高于正则匹配:
db.coll_1.aggregate([ // 新增字段标记当前文档是否匹配 { $addFields: { isMatch: { $eq: [ "$field_1", { $substrCP: ["$field_2", 0, 2] } // 截取field_2前2位字符 ] } } }, // 按匹配状态分组统计数量 { $group: { _id: "$isMatch", count: { $sum: 1 } } } ])
返回结果说明:
_id: true对应的count值为匹配的文档数量_id: false对应的count值为不匹配的文档数量
正则实现方案(性能略低,不推荐)
如果需要用正则逻辑实现,可以用$regexMatch动态拼接正则规则:
db.coll_1.aggregate([ { $addFields: { isMatch: { $regexMatch: { input: "$field_2", regex: { $concat: ["^", "$field_1"] } } } } }, { $group: { _id: "$isMatch", count: { $sum: 1 } } } ])
原有遍历写法修正(极端不推荐,执行耗时极长)
如果坚持用遍历逻辑实现,修正后代码如下,仅作错误演示参考:
let match = 0, mismatch = 0 db.coll_1.find({ field_1: { $exists: true }, field_2: { $exists: true } }).forEach(doc => { doc.field_2.startsWith(doc.field_1) ? match++ : mismatch++ }) print(`匹配数量:${match},不匹配数量:${mismatch}`)
内容的提问来源于stack exchange,提问作者jiwooshim
相关产品推荐
相关产品推荐

