Appearance
一般来说,对 mongodb 中某个字符串字段
进行排序 是按 二进制
排序的
那么如果 类似 "123"
这种数据,能否按 数值的规则排序 > "20"
吗?
答案是有的,这里用到的是 Mongodb 索引中的 collation
我们创建一个表,里面写入 3 条数据,value 字段都是字符串类型的数值
db.createCollection('test');
db.test.insert({ value: '12345' });
db.person.insert({ value: '2345' });
db.person.insert({ value: '3456' });
对 value 字段进行排序
db.test.find({}).sort({ value: -1 })
{"_id" : ObjectId("5e7606e476d53a453c7135e8"),"value" : "3456"},
{"_id" : ObjectId("5e7606dd76d53a453c7135e7"),"value" : "2345"},
{"_id" : ObjectId("5e7606d276d53a453c7135e6"),"value" : "12345"},
不出意外的 是按照 value 的第一位 的 3 > 2 > 1 排的序
我们这里在 sort 前加上 collation 方法
db.test.find({}).collation({ locale: 'en', numericOrdering: true }).sort({ value: -1 })
{"_id" : ObjectId("5e7606d276d53a453c7135e6"),"value" : "12345"},
{"_id" : ObjectId("5e7606e476d53a453c7135e8"),"value" : "3456"},
{"_id" : ObjectId("5e7606dd76d53a453c7135e7"),"value" : "2345"},
这样就对 字符串 value 以数值的规则 进行了排序
Mongodb collation 详解
Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks.
简而言之,Collation 允许 MongoDB 用户根据 不同的语言 定制 排序规则,举个例子,一个存储中国用户信息的集合。
db.createCollection('person');
db.person.insert({ name: '张三' });
db.person.insert({ name: '李四' });
db.person.insert({ name: '王五' });
db.person.insert({ name: '马六' });
db.person.insert({ name: '张七' });
默认情况下,名字字段会被当做一个普通的二机制字符串来对比,按照 name 字段排序的结果如下
db.person.find().sort({name: 1})
{ "_id" : ObjectId("586b98980cec8d86881cffac"), "name" : "张七" }
{ "_id" : ObjectId("586b98980cec8d86881cffa8"), "name" : "张三" }
{ "_id" : ObjectId("586b98980cec8d86881cffa9"), "name" : "李四" }
{ "_id" : ObjectId("586b98980cec8d86881cffaa"), "name" : "王五" }
{ "_id" : ObjectId("586b98980cec8d86881cffab"), "name" : "马六" }
而对于中文名字,通常有按拼音顺序排序的需求,这时就可以通过 collation 来搞定
db.createCollection('person', { collation: { locale: 'zh' } });
db.person.insert({ name: '张三' });
db.person.insert({ name: '李四' });
db.person.insert({ name: '王五' });
db.person.insert({ name: '马六' });
db.person.insert({ name: '张七' });
我们这里 插入几个 中文人名
db.createCollection('person', { collation: { locale: 'zh' } });
db.person.insert({ name: '张三' });
db.person.insert({ name: '李四' });
db.person.insert({ name: '王五' });
db.person.insert({ name: '马六' });
db.person.insert({ name: '张七' });
此时再按 name 字段排序,则会按照 locale 指定的中文规则来排序
db.person.find().sort({name: 1})
{ "_id" : ObjectId("586b995d0cec8d86881cffae"), "name" : "李四" }
{ "_id" : ObjectId("586b995d0cec8d86881cffb0"), "name" : "马六" }
{ "_id" : ObjectId("586b995d0cec8d86881cffaf"), "name" : "王五" }
{ "_id" : ObjectId("586b995d0cec8d86881cffb1"), "name" : "张七" }
{ "_id" : ObjectId("586b995d0cec8d86881cffad"), "name" : "张三" }
MongoDB 3.4 里,基本所有涉及字符串字段排序
的命令,都支持指定 collation,比如「创建集合、创建索引、find」等;上述例子里在 createCollection 的时候指定了 collation,则该集合里所有字符串默认都会按指定的 collation 来排序,如果只想针对某一个字段来指定 collation,可以该字段创建指定 collation 的索引,例如
db.person.createIndex({ name: 1 }, { collation: { locale: 'zh' } });