大文字と小文字を区別せずに、特定のフィールドでMongoDBコレクションを並べ替えるにはどうすればよいですか?デフォルトでは、a-zの前にA-Zが付きます。
Javaを使用しています。
更新:現在、mongodbには大文字と小文字を区別しないインデックスがあります:
Users.find({})
.collation({locale: "en" })
.sort({name: 1})
.exec()
.then(...)
シェル:
db.getCollection('users')
.find({})
.collation({'locale':'en'})
.sort({'firstName':1})
更新:この回答は古く、3.4では大文字と小文字を区別しないインデックスが使用されます。詳細については、JIRAを参照してください https://jira.mongodb.org/browse/SERVER-9
残念ながら、MongoDBにはまだ大文字と小文字を区別しないインデックスがありません。 https://jira.mongodb.org/browse/SERVER-9 で、タスクはプッシュバックされています。
つまり、現在大文字と小文字を区別しないで並べ替える唯一の方法は、実際に特定の「小文字」フィールドを作成し、問題の並べ替えフィールドの値(もちろん小文字)をコピーし、代わりに並べ替えることです。
MongoDBではソートはそのように機能しますが、集約を使用してその場でソートを実行できます。
次のデータを取得します。
{ "field" : "BBB" }
{ "field" : "aaa" }
{ "field" : "AAA" }
そのため、次のステートメントを使用します。
db.collection.aggregate([
{ "$project": {
"field": 1,
"insensitive": { "$toLower": "$field" }
}},
{ "$sort": { "insensitive": 1 } }
])
次のような結果が生成されます。
{
"field" : "aaa",
"insensitive" : "aaa"
},
{
"field" : "AAA",
"insensitive" : "aaa"
},
{
"field" : "BBB",
"insensitive" : "bbb"
}
実際の挿入順序は、変換時に同じキーになるすべての値に対して維持されます。
これは、MongoDB JIRAではかなり長い間 issue でしたが、現在は解決されています。 詳細なドキュメントについてはこのリリースノート をご覧ください。 collation
を使用する必要があります。
User.find()
.collation({locale: "en" }) //or whatever collation you want
.sort({name:'asc'})
.exec(function(err, users) {
// use your case insensitive sorted results
});
現在(mongodb 4)では、次のことができます。
mongo Shell:
db.getCollection('users')
.find({})
.collation({'locale':'en'})
.sort({'firstName':1});
マングース:
Users.find({})
.collation({locale: "en" })
.sort({name: 1})
.exec()
.then(...)
サポートされている言語とロケール mongodbです。
これはJavaにあります。引数なしと最初のkey-valのBasicDBObject
のバリエーションを混在させる
DBCollection coll = db.getCollection("foo");
List<DBObject> pipe = new ArrayList<DBObject>();
DBObject prjflds = new BasicDBObject();
prjflds.put("field", 1);
prjflds.put("insensitive", new BasicDBObject("$toLower", "$field"));
DBObject project = new BasicDBObject();
project.put("$project", prjflds);
pipe.add(project);
DBObject sort = new BasicDBObject();
sort.put("$sort", new BasicDBObject("insensitive", 1));
pipe.add(sort);
AggregationOutput agg = coll.aggregate(pipe);
for (DBObject result : agg.results()) {
System.out.println(result);
}
コード.collation({'locale':'en'})
を追加すると、問題の解決に役立ちました。