MongoDB中实现不区分大小写搜索的非正则高效方案有哪些?
MongoDB高效实现大小写不敏感等值查询的可行方案
- 方案1:使用Collation(排序规则)索引(推荐,MongoDB 3.2及以上版本支持)
这个是官方原生支持的最优方案,性能和普通等值查询完全一致,不需要额外存储冗余字段。
第一步先给查询字段创建指定大小写不敏感的索引:
这里db.student.createIndex( { name: 1 }, { collation: { locale: "en", strength: 2 } } )strength: 2表示匹配时忽略大小写和字符重音,符合大小写不敏感的需求。
查询时携带相同的collation参数即可:
不管查询值是vicky、VICKY还是Vicky,都能匹配到name为Vicky的文档,且全程命中索引。db.student.find({ name: "vicky" }).collation({ locale: "en", strength: 2 }) - 方案2:预存标准化小写字段(兼容所有MongoDB版本)
如果使用的是3.2以下的老版本MongoDB,可以在写入数据时新增一个冗余的小写字段,存储原始字段的全小写值:
写入示例:
给db.student.insertOne({ _id: ObjectId("something"), name: "Vicky", name_lower: "vicky" // 预存全小写值 })name_lower字段创建普通单键索引:
查询时先把查询参数转为小写,再匹配db.student.createIndex({ name_lower: 1 })name_lower字段即可:
该方案性能同样极高,缺点是需要额外存储冗余字段,写入时多一步字符转换操作。const searchName = "VICKY" db.student.find({ name_lower: searchName.toLowerCase() }) - 方案3:文本索引(适合模糊搜索场景)
如果你的需求是模糊匹配而非严格等值查询,可以给name字段创建文本索引,文本索引默认大小写不敏感:
创建索引:
查询示例:db.student.createIndex({ name: "text" })
注意该方案是全文检索逻辑,会拆分关键词匹配,不适合严格的等值查询场景。db.student.find({ $text: { $search: "vicky" } })
不推荐使用带
i选项的正则表达式实现大小写不敏感查询:除了前缀匹配的正则(如/^vicky/i)能部分命中索引外,大部分正则查询会触发全表扫描,数据量较大时性能会出现指数级下降。
内容的提问来源于stack exchange,提问作者Gnanavel
相关产品推荐
相关产品推荐

