アップデート: :バージョン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を使用する際の推奨事項は、混合ケースのある文字列を並べ替える必要がある場合は、文字列を2回保存することです。
"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}},
]);