MongoDB不区分大小写和utf-8排序

时间:2014-03-14 22:58:43

标签: mongodb sorting utf-8 natural-sort

我将这些文档保存在MongoDB集合中:

{ "_id" : ObjectId("5323850fa89de4a9f691dacf"), "name" : "B" }
{ "_id" : ObjectId("53238511a89de4a9f691dad0"), "name" : "a" }
{ "_id" : ObjectId("53238515a89de4a9f691dad1"), "name" : "A" }
{ "_id" : ObjectId("53238522a89de4a9f691dad2"), "name" : "z" }
{ "_id" : ObjectId("5323852ea89de4a9f691dad3"), "name" : "X" }
{ "_id" : ObjectId("5323855ea89de4a9f691dad4"), "name" : "á" }

然后我按名称查询排序:

db.collection.find().sort({name:1});

结果是:

{ "_id" : ObjectId("53238515a89de4a9f691dad1"), "name" : "A" }
{ "_id" : ObjectId("5323850fa89de4a9f691dacf"), "name" : "B" }
{ "_id" : ObjectId("5323852ea89de4a9f691dad3"), "name" : "X" }
{ "_id" : ObjectId("53238511a89de4a9f691dad0"), "name" : "a" }
{ "_id" : ObjectId("53238522a89de4a9f691dad2"), "name" : "z" }
{ "_id" : ObjectId("5323855ea89de4a9f691dad4"), "name" : "á" }

我发现MongoDB不仅doesn't support utf-8 sorting,而且它似乎也不支持不区分大小写的排序。

支持这两种排序的最佳解决方案是什么?

(我在Node web应用程序中使用Mongoose和Express)

2 个答案:

答案 0 :(得分:0)

您可以使用aggregation framework来实现此目的。更具体地说,您可以使用$project运算符使用$toLower创建名称的小写版本,然后对其进行排序。

示例:

db.test.aggregate([
    {$project:{name:1, nameLower:{$toLower:"$name"}}}, 
    {$sort:{nameLower:1}}
])

注意:正如文档中引用的那样:

  

$ toLower在应用于罗马字母之外的字形时可能没有意义。

您提供的样本数据集的输出:

db.test.aggregate([{$project:{name:1, nameLower:{$toLower:"$name"}}}, {$sort:{nameLower:1}}])
{
        "result" : [
                {
                        "_id" : ObjectId("5324387e87861ff5f2696216"),
                        "name" : "a",
                        "nameLower" : "a"
                },
                {
                        "_id" : ObjectId("5324388687861ff5f2696217"),
                        "name" : "A",
                        "nameLower" : "a"
                },
                {
                        "_id" : ObjectId("5324387987861ff5f2696215"),
                        "name" : "B",
                        "nameLower" : "b"
                },
                {
                        "_id" : ObjectId("5324389187861ff5f2696219"),
                        "name" : "X",
                        "nameLower" : "x"
                },
                {
                        "_id" : ObjectId("5324388a87861ff5f2696218"),
                        "name" : "z",
                        "nameLower" : "z"
                },
                {
                        "_id" : ObjectId("53243ab087861ff5f269621a"),
                        "name" : "á",
                        "nameLower" : "á"
                }
        ],
        "ok" : 1
}

答案 1 :(得分:0)

从v3.4(2016年11月发布)开始,MongoDB支持按排序规则(SERVER-1920-Release Notes)进行排序:

> db.myColl.insert([{_id: 1, "term": "cote"}, {_id: 2, "term": "coté"}, {_id: 3, "term" : "côte"}, {_id: 4, "term" : "côté"}])
Inserted 1 record(s) in 56ms

> db.myColl.find().sort({"term": -1})
{ "_id": 4, "term": "côté" }
{ "_id": 3, "term": "côte" }
{ "_id": 2, "term": "coté" }
{ "_id": 1, "term": "cote" }

> db.myColl.find().sort({"term": -1}).collation({"locale": "fr_CA"})
{ "_id": 4, "term": "côté" }
{ "_id": 2, "term": "coté" }
{ "_id": 3, "term": "côte" }
{ "_id": 1, "term": "cote" }

有关collation()方法和此处示例的更多选项:https://docs.mongodb.com/manual/reference/method/cursor.collation/#examples

它支持以下语言环境: https://docs.mongodb.com/manual/reference/collation-locales-defaults/#collation-languages-locales

另请参阅Derick Rethans出色的blog post on Natural Language Sorting