如何在MongoDB中解析HTML标签内容解决mongoose排序异常问题
解决方案
方案1:使用MongoDB聚合查询直接处理(无需修改现有数据结构)
适合MongoDB 4.4及以上版本,直接在查询侧提取HTML纯文本后排序,示例代码如下:
YourModel.aggregate([ // 新增临时字段存储提取后的英文纯文本 { $addFields: { sortedText: { // 先替换所有HTML标签为空 $replaceAll: { input: { $replaceAll: { input: "$question.en", find: /<[^>]*>/g, replacement: "" } }, // 再替换掉换行、多余空格 find: /\s+/g, replacement: " " } } } }, // 按提取后的纯文本升序排序,要降序就写-1 { $sort: { sortedText: 1 } }, // 移除临时字段,不影响返回结果结构 { $unset: "sortedText" } ])
注意:如果你的MongoDB版本不支持
$replaceAll的正则匹配,可以改用$regexFind迭代提取文本,或者直接用方案2。
方案2:预存纯文本字段(推荐生产环境使用)
在写入数据的时候就提前提取好HTML对应的纯文本,单独存为排序专用字段,后续排序直接调用,性能远高于实时聚合处理,操作步骤如下:
- 修改Mongoose Schema,新增纯文本存储字段:
const questionSchema = new mongoose.Schema({ question: { en: String, hn: String, enPureText: String // 新增字段,专门用来排序 } })
- 加pre save钩子,写入数据时自动提取纯文本:
questionSchema.pre('save', function(next) { if (this.isModified('question.en')) { // 提取HTML纯文本,去掉标签和多余空白 this.question.enPureText = this.question.en .replace(/<[^>]*>/g, '') .replace(/\s+/g, ' ') .trim() } next() })
- 后续排序直接调用该字段即可:
YourModel.find().sort('question.enPureText').exec()
针对存量数据,可以写一个批量更新脚本,一次性把所有数据的
enPureText字段计算补全即可。
内容的提问来源于stack exchange,提问作者Sachin Yadav
相关产品推荐
相关产品推荐

