7

当我尝试对一个字符串字段(此处Title)的集合进行排序时,排序未按预期工作。请看下面:

db.SomeCollection.find().limit(50).sort({ "Title" : -1 });

实际结果顺序

  • “书名”:“geog.3 学生用书”
  • “标题”:“geog.2 学生用书”
  • “标题”:“geog.1 学生用书”
  • “标题”:“佐伊和斯威夫特”
  • “标题”:“主题公园的拉链”
  • “标题”:“超市邮编”

预期结果顺序

  • “标题”:“佐伊和斯威夫特”
  • “标题”:“主题公园的拉链”
  • “标题”:“超市邮编”
  • “书名”:“geog.3 学生用书”
  • “标题”:“geog.2 学生用书”
  • “标题”:“geog.1 学生用书”

当我尝试按日期字段排序时,也会出现同样的问题。

有什么建议么?

4

5 回答 5

6

更新:3.4 版具有不区分大小写的索引

这是一个已知的问题。MongoDB 不支持对字符串进行词法排序(JIRA:String lexicographical ordering)。您应该在应用程序代码中对结果进行排序,或者使用数字字段进行排序。它应该可靠地对日期字段进行排序。你能举一个按日期排序不起作用的例子吗?

于 2013-11-08T09:11:48.250 回答
3

究竟是什么让你感到惊讶?

它根据符号的数字表示的表示进行排序。如果你看这里(我知道 mongodb 以 UTF-8 存储字符串,所以这只是为了教育目的)。您将看到大写字母对应的数字低于小写字母。这样他们就会走在前面。

Mongodb 无法根据本地化或不区分大小写对字母进行排序。

在你的情况下g有更高的数字 then Z,所以它排在第一位(按降序排序)。然后3有相应的数字高于21。所以基本上一切都是正确的。

于 2013-11-08T09:22:33.820 回答
3

如果您使用聚合预期输出是可能的,见下文:

    db.collection.aggregate([
    {
        “$项目”:{
           “标题”:1,        
           “输出”:{“$toLower”:“$Title”}       
        }},
        { "$sort": { "输出":-1 } },
        {"$project": {"Title": 1, "_id":0}}
    ])


它会给你预期的输出如下:

    {
        “结果” : [
            {
                “标题”:“佐伊和斯威夫特”
            },
            {
                “标题”:“主题公园的拉链”
            },
            {
                “标题”:“超市邮编”
            },
            {
                “书名”:“geog.3 学生用书”
            },
            {
                “标题”:“geog.2 学生用书”
            },
            {
                “标题”:“geog.1 学生用书”
            }
        ],
        “好”:1
    }

于 2014-05-09T13:11:47.237 回答
2

从没有正确排序的日期开始......

如果您将日期存储为string,则它需要可作为字符串排序。这很简单:

2013-11-08  // yyyy-mm-dd (the dashes would be optional)

只要日期字符串的每一段都0正确填充,字符串就会自然地按照您期望的方式排序。

完整的日期时间通常以 UTC 格式存储:

2013-11-23T10:46:01.914Z

但是,我还建议您不要将日期值存储为字符串,而是考虑使用本机 MongoDB Date 是否更有意义(参考)。如果你看一下 MongoDb 的聚合框架,你会发现有很多函数可以操作这些日期,而字符串非常有限。

至于字符串排序,有人指出它的排序就像计算机存储数据,而不是你作为人的排序方式。如果您考虑将字符串存储为其 ASCII/UTF-8 表示形式,您应该会看到为什么排序会这样工作:

Zoe = [90, 111, 101]
geo = [103, 101, 111]

如果您要按照您指定的降序对它们进行排序,您应该看到"geo"'s 的内部字节表示如何大于字符串的表示"Zoe"(在这种情况下103排序高于)。90

通常,使用 MongoDb 时,如果您需要对大小写混合的字符串进行排序,建议将字符串存储两次:

  1. 原始字符串 ( "Title")
  2. 作为规范化字符串。例如,可能全部为“小写”,可能带有重音字符也转换为普通字符。因此,您最终会得到一个名为"SortedTitle"example 的新字段,您的代码将使用它进行排序,但会Title"向用户显示实际的 "。
于 2013-11-08T12:14:54.517 回答
0

如果您在 ror 和 mongomapper 中进行操作,请按照以下步骤操作:

我取了我的模型名称 abc 并获取 Title 的结果。

@test_abc_details_array_full=Abc.collection.aggregate([

     {"$project"=> {
       "Title"=> 1,        
       "output"=> { "$toLower"=> "$Title" }       
    }},
    { "$sort"=> {  "output"=>1 } },        
    {"$project"=> {Title: 1, _id:0}},

  ]); 
于 2015-03-19T13:06:19.553 回答