web-dev-qa-db-ja.com

MongoDBの大文字と小文字を区別しないソート

大文字と小文字を区別せずに、特定のフィールドでMongoDBコレクションを並べ替えるにはどうすればよいですか?デフォルトでは、a-zの前にA-Zが付きます。

Javaを使用しています。

49
Varun Kumar

更新:現在、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 で、タスクはプッシュバックされています。

つまり、現在大文字と小文字を区別しないで並べ替える唯一の方法は、実際に特定の「小文字」フィールドを作成し、問題の並べ替えフィールドの値(もちろん小文字)をコピーし、代わりに並べ替えることです。

41
Sammaye

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"
}

実際の挿入順序は、変換時に同じキーになるすべての値に対して維持されます。

40
Neil Lunn

これは、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
    });
15

現在(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です。

2
Wajahath

これは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);
        }
1
Buzz Moschetti

コード.collation({'locale':'en'})を追加すると、問題の解決に役立ちました。

1
Monu Chaudhary