更新: :3.4版本 案例不敏感索引
这是一个已知的问题。 MongoDB不支持字符串的词汇分类(Jira:弦词典顺序)。您应该在应用程序代码中对结果进行排序,或使用数字字段进行排序。它应该可靠地对日期字段进行排序。您可以举一个按日期排序不起作用的示例吗?
题
当我尝试对集合字符串进行分类时(此处 Title
),排序无法正常工作。请参阅下面:
db.SomeCollection.find().limit(50).sort({ "Title" : -1 });
实际结果顺序
预期结果顺序
当我尝试按日期字段进行排序时,也会发生同样的问题。
有什么建议么?
解决方案
更新: :3.4版本 案例不敏感索引
这是一个已知的问题。 MongoDB不支持字符串的词汇分类(Jira:弦词典顺序)。您应该在应用程序代码中对结果进行排序,或使用数字字段进行排序。它应该可靠地对日期字段进行排序。您可以举一个按日期排序不起作用的示例吗?
其他提示
你到底让你感到惊讶吗?
它基于符号的数值表示形式的呈现。如果你看 这里 (我知道MongoDB将字符串存储在UTF-8中,因此仅出于教育目的)。您会看到上部案例字母的相应数字低于较低的案例字母。因此,他们会走在前面。
MongoDB无法根据本地化或病例不敏感对字母进行排序。
就你而言 g
那么数字更高 Z
, ,因此首先进行(以减少顺序排序)。接着 3
当时有相应的数字 2
和 1
. 。因此,基本上一切都是正确的。
如果您使用聚合预期输出,请参见下面:
db.collection.aggregate([ { "$project": { "Title": 1, "output": { "$toLower": "$Title" } }}, { "$sort": { "output":-1 } }, {"$project": {"Title": 1, "_id":0}} ])
它会给你 预期输出 如下:
{ "result" : [ { "Title" : "Zoe and Swift" }, { "Title" : "Zip at the Theme Park" }, { "Title" : "Zip at the Supermarket" }, { "Title" : "geog.3 students' book" }, { "Title" : "geog.2 students' book" }, { "Title" : "geog.1 students' book" } ], "ok" : 1 }
从无法正确排序的日期开始。
如果您将日期存储为 string
, ,它需要作为字符串排序。很简单:
2013-11-08 // yyyy-mm-dd (the dashes would be optional)
只要将日期字符串的每一部分都填充 0
正确地,琴弦将自然地和您期望的方式分类。
全约日期通常存储在UTC中:
2013-11-23T10:46:01.914Z
但是,我也建议您而不是将日期值存储为字符串,而是考虑使用本机MongoDB日期是否更有意义(参考)。如果您查看MongoDB的聚合框架,您会发现有很多 功能 可以操纵这些日期,而字符串非常有限。
至于字符串排序,已经指出,它的排序就像计算机存储数据,而不是您作为一个人进行排序的方式。如果您认为字符串存储为其ASCII/UTF-8表示,则应该了解为什么分类以其方式工作:
Zoe = [90, 111, 101]
geo = [103, 101, 111]
如果您要按照指定的方式对降顺序进行排序,则应查看如何 "geo"
的内部字节表示大于字符串 "Zoe"
(和 103
排序高于 90
在这种情况下)。
通常,使用MongoDB时的建议是将字符串存储两次,如果您需要对具有混合情况的字符串进行分类:
"Title"
)"SortedTitle"
例如,您的代码将使用它来排序,但显示实际的”Title"
给用户。 如果您在ROR和MONGOMAPPER中进行操作,请按照以下步骤操作:
我采用了我的模型名称ABC,并获取标题的结果。
@test_abc_details_array_full=Abc.collection.aggregate([
{"$project"=> {
"Title"=> 1,
"output"=> { "$toLower"=> "$Title" }
}},
{ "$sort"=> { "output"=>1 } },
{"$project"=> {Title: 1, _id:0}},
]);