← 返回题目列表

MongoDB Collation 是什么?如何实现大小写不敏感查询?

中等 第 28 / 31 题 更新于 2026/07/30
MongoDBCollation排序规则大小写不敏感

简化版

Collation 用来定义字符串比较规则,包括语言、大小写、重音符号等。要让大小写不敏感查询高效,查询和索引通常要使用一致的 collation。

详细版

MongoDB 默认字符串比较通常是二进制语义,Appleapple 不一定按业务期望相等。Collation 可以指定比较规则,让查询、排序、唯一索引按特定语言规则工作。

  • 常用参数包括 localestrengthstrength 越低越忽略大小写、重音等差异。
  • 可以在集合、索引或单次查询上指定 collation。
  • 如果索引有 collation,查询也要使用兼容 collation,才更可能走该索引。
  • 大小写不敏感唯一约束可以通过带 collation 的唯一索引实现。
  • 不要把 collation 和把字段统一转小写混为一谈;一个是比较规则,一个是数据规范化策略。

完整版教学

一、为什么默认字符串比较不够用

业务里的字符串往往有语言语义,而数据库底层比较默认更接近字节或码点顺序。用户注册邮箱时,很多业务希望 Tom@example.comtom@example.com 被视为同一个邮箱;商品名称排序时,也可能希望大小写不要影响结果。Collation 就是把“字符串怎么比较”这件事从应用代码里拿出来,交给数据库在查询、排序和索引层统一处理。没有 collation 时,你可能会写很多 toLowerCase(),但这会带来索引失效和数据一致性问题。

db.users.find({ email: "tom@example.com" })
  .collation({ locale: "en", strength: 2 })

记忆钩子:Collation 不是改变字符串本身,而是改变“比较字符串时戴的眼镜”。

二、localestrength 怎么理解

locale 决定按哪种语言规则比较,strength 决定比较敏感度。简单理解,较低的 strength 会忽略更多差异,例如大小写、重音符号;较高的 strength 会比较得更细。大小写不敏感常见配置是 strength: 2,但具体要结合语言和业务测试。面试时不用背所有参数,但要知道 collation 的核心不是“开关”,而是一套比较规则。

示例理解:
strength 1:更粗粒度,可能忽略大小写和重音
strength 2:常用于大小写不敏感,但保留部分字符差异
strength 3:更敏感,通常区分大小写

三、索引和查询 collation 必须对得上

很多人以为给查询加 .collation() 就够了,但高性能查询还要考虑索引。索引在建立时如果使用了某种 collation,索引中的字符串顺序就是按这套规则组织的。查询使用不同 collation 时,数据库可能不能直接复用这个索引,因为比较规则不一致会导致顺序和等值判断不同。因此大小写不敏感查询如果要高效,通常要建立同规则索引,并在查询时指定同样规则。

db.users.createIndex(
  { email: 1 },
  { collation: { locale: "en", strength: 2 } }
)

db.users.find({ email: "TOM@example.com" })
  .collation({ locale: "en", strength: 2 })

四、大小写不敏感唯一索引的场景

注册邮箱、用户名、租户内编码等字段,常常需要大小写不敏感唯一。只在应用层把字符串转小写校验是不够的,因为并发请求可能绕过应用检查,最终还是要数据库唯一约束兜底。带 collation 的唯一索引可以让 Tomtom 在索引比较规则下冲突,从而挡住重复写入。这类设计要提前定好规则,因为后续修改唯一索引通常涉及数据清洗。

方案优点风险
应用层转小写简单直观并发下仍需数据库兜底
原字段 + collation 唯一索引保留展示格式要统一查询 collation
额外 normalized 字段可控、跨库通用多维护一个字段

五、带数字看为什么不能只靠应用校验

假设两个注册请求同时到达:请求 A 检查 Tom 不存在,请求 B 检查 tom 也不存在。如果没有数据库唯一约束,两个请求都可能写入成功,之后业务就出现两个逻辑重复账号。并发量越高,这种时间窗口越容易暴露。数据库唯一索引把检查和写入变成原子约束,哪怕两个请求只差 5 毫秒,也只能有一个成功。

T0: A 查询 Tom 不存在
T1: B 查询 tom 不存在
T2: A 插入成功
T3: B 插入成功(如果没有唯一索引)

六、Collation 和规范化字段怎么取舍

Collation 的优点是保留原始展示值,同时让比较规则符合业务。规范化字段的优点是简单、可移植,例如额外维护 emailLower,所有查询都查小写字段。两种方案没有绝对优劣:如果团队熟悉 MongoDB collation,并且查询都能统一指定规则,collation 很自然;如果业务跨多个存储系统,或者规则想完全掌控,normalized 字段也很常见。关键是不要一半查询用 collation,一半查询用 lower 字段,最后一致性会变差。

// normalized 字段方案
{ email: "Tom@example.com", emailLower: "tom@example.com" }
db.users.createIndex({ emailLower: 1 }, { unique: true })

七、常见误区与追问

  • 误区:Collation 会把数据自动转成小写。 它改变比较规则,不改变存储的原始字符串。
  • 误区:查询加 collation 就一定走索引。 查询 collation 必须和索引规则兼容,否则可能无法使用对应索引。
  • 误区:大小写不敏感只要应用层判断。 并发写入下应用检查有时间窗口,数据库唯一约束才是兜底。
  • 追问:用户名保留原大小写怎么做唯一? 可用带 collation 的唯一索引,或维护 normalized 字段并建唯一索引。
  • 追问:排序也受 collation 影响吗? 受影响,因为 collation 定义了字符串比较顺序,排序和等值判断都可能变化。

八、加强记忆

Collation 可以记成“字符串比较规则”。它不改数据,只改查询、排序、唯一约束判断字符串时的规则。面试里按三步答:为什么需要它,因为业务字符串比较不是纯字节比较;怎么用它,索引和查询要指定一致规则;哪里容易错,大小写不敏感唯一必须靠数据库约束兜底,不能只靠应用层检查。