web-dev-qa-db-fra.com

Tri insensible à la casse dans MongoDB

Comment puis-je trier une collection MongoDB par champ donné, sans tenir compte de la casse? Par défaut, je reçois A-Z avant a-z.

J'utilise Java.

49
Varun Kumar

Mise à jour: Pour l'instant mongodb a des index insensibles à la casse:

Users.find({})
  .collation({locale: "en" })
  .sort({name: 1})
  .exec()
  .then(...)

Coquille:

db.getCollection('users')
  .find({})
  .collation({'locale':'en'})
  .sort({'firstName':1})

Mise à jour: Cette réponse est obsolète, 3.4 aura des index insensibles à la casse. Consultez le JIRA pour plus d'informations https://jira.mongodb.org/browse/SERVER-9


Malheureusement, MongoDB n'a pas encore d'index insensibles à la casse: https://jira.mongodb.org/browse/SERVER-9 et la tâche a été repoussée.

Cela signifie que la seule façon de trier actuellement la casse est de créer un champ spécifique "inférieur", en copiant la valeur (inférieure bien sûr) du champ de tri en question et de le trier à la place.

41
Sammaye

Le tri fonctionne comme ça dans MongoDB mais vous pouvez le faire à la volée avec l'agrégat:

Prenez les données suivantes:

{ "field" : "BBB" }
{ "field" : "aaa" }
{ "field" : "AAA" }

Donc, avec la déclaration suivante:

db.collection.aggregate([
    { "$project": {
       "field": 1,
       "insensitive": { "$toLower": "$field" }
    }},
    { "$sort": { "insensitive": 1 } }
])

Produirait des résultats comme:

{
    "field" : "aaa",
    "insensitive" : "aaa"
},
{
    "field" : "AAA",
    "insensitive" : "aaa"
},
{
    "field" : "BBB",
    "insensitive" : "bbb"
}

L'ordre d'insertion réel serait conservé pour toutes les valeurs résultant dans la même clé lors de la conversion.

40
Neil Lunn

Cela a été un problème pendant assez longtemps sur MongoDB JIRA, mais il est maintenant résolu. Jetez un œil à ces notes de version pour une documentation détaillée . Vous devez utiliser 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
Mladen Janjetovic

À partir de maintenant (mongodb 4), vous pouvez effectuer les opérations suivantes:

mongo Shell:

db.getCollection('users')
  .find({})
  .collation({'locale':'en'})
  .sort({'firstName':1});

mangouste:

Users.find({})
  .collation({locale: "en" })
  .sort({name: 1})
  .exec()
  .then(...)

Voici langues et paramètres régionaux pris en charge par mongodb.

2
Wajahath

Le voici en Java. J'ai mélangé des no-args et des premières variantes de valeur-clé de BasicDBObject juste pour la variété

        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

L'ajout du code .collation({'locale':'en'}) a aidé à résoudre mon problème.

1
Monu Chaudhary