NodeJS结合MongoDB实现含指定字符串且前缀优先的模糊查询排序
NodeJS + MongoDB 实现带前缀优先级的模糊查询排序
需求说明
现有症状数据如下:
- 腹部绞痛(Abdominal Cramp)
- 失写症(Agraphia)
- 无热(Afebrile)
- 周期性发热(Cyclic Fever)
- 发热(Fever)
- 高热(High Fever)
- 持续发热(Continuous Fever)
需要实现:搜索关键词fe时,返回所有包含fe的条目,且以fe开头的结果排在最前列,最终期望顺序为:
- 发热(Fever)
- 无热(Afebrile)
- 持续发热(Continuous Fever)
- 周期性发热(Cyclic Fever)
- 高热(High Fever)
解决方案
方法一:使用MongoDB聚合管道
通过聚合管道多阶段处理,先筛选匹配数据,再自定义排序权重,最终得到符合要求的排序结果:
const searchKeyword = "fe"; // 转义正则特殊字符,避免匹配异常 const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const escapedKeyword = escapeRegExp(searchKeyword); const result = await db.collection('symptoms').aggregate([ // 1. 筛选所有包含关键词的文档(不区分大小写) { $match: { name: { $regex: escapedKeyword, $options: 'i' } } }, // 2. 为前缀匹配的文档添加高优先级标记 { $addFields: { priority: { $cond: { if: { $regexMatch: { input: "$name", regex: `^${escapedKeyword}`, options: 'i' } }, then: 1, // 前缀匹配的优先级为1 else: 0 // 仅包含关键词的优先级为0 } } } }, // 3. 先按优先级降序,再按名称升序排列 { $sort: { priority: -1, name: 1 } }, // 4. 移除临时的优先级字段(可选) { $project: { priority: 0 } } ]).toArray();
方法二:使用Find查询结合自定义排序
若不需要复杂聚合操作,可直接在find后通过$expr定义排序规则:
const searchKeyword = "fe"; const escapedKeyword = escapeRegExp(searchKeyword); const result = await db.collection('symptoms').find({ name: { $regex: escapedKeyword, $options: 'i' } }).sort({ $expr: { $cond: { if: { $regexMatch: { input: "$name", regex: `^${escapedKeyword}`, options: 'i' } }, then: 1, else: 0 } }, name: 1 }).toArray();
关键逻辑说明
- 模糊匹配:使用
$regex结合i选项实现不区分大小写的包含匹配。 - 优先级排序:通过
$cond和$regexMatch判断文档是否以关键词开头,为这类文档赋予更高排序权重,确保其排在前列。 - 二次排序:同一优先级内按名称升序排列,保证结果顺序的一致性。
内容的提问来源于stack exchange,提问作者Mehul Sonagara
相关产品推荐
相关产品推荐

