MongoDB возвращает капитализированные строки сначала при сортировке

StackOverflow https://stackoverflow.com/questions/19855147

  •  29-07-2022
  •  | 
  •  

Вопрос

Когда я попытался сортировать коллекцию поля струн (здесь Title), сортировка не работает, как и ожидалось. Пожалуйста, смотрите ниже:

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

Фактический порядок результатов

  • «Название»: «Geog.3 Книга студентов»
  • «Название»: «Geog.2 Книга студентов»
  • «Название»: «Geog.1 Книга студентов»
  • "Название": "Зои и Свифт"
  • «Название»: "Zip в тематическом парке"
  • «Название»: "Zip в супермаркете"

Ожидаемый порядок результатов

  • "Название": "Зои и Свифт"
  • «Название»: "Zip в тематическом парке"
  • «Название»: "Zip в супермаркете"
  • «Название»: «Geog.3 Книга студентов»
  • «Название»: «Geog.2 Книга студентов»
  • «Название»: «Geog.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 состоит в том, чтобы хранить строки дважды, если вам нужно сортировать строку, которая имеет смешанный корпус:

  1. Оригинальная строка ("Title")
  2. Как нормализованная строка. Возможно, например, все как «строчные», возможно, с акцентированными символами также преобразованы в общий символ. Итак, вы получите новое поле под названием "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}},

  ]); 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top