Как я могу отсортировать коллекцию MongoDB по заданному полю без учета регистра? По умолчанию я получаю AZ перед AZ.
Сортировка без учета регистра в MongoDB
Ответы (10)
Обновление: На данный момент 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-90< /а>
К сожалению, в MongoDB пока нет индексов, нечувствительных к регистру: https://jira.mongodb.org/browse/SERVER-90 и задача была отложена.
Это означает, что единственный способ сортировки без учета регистра в настоящее время - это фактически создать конкретное поле «в нижнем регистре», скопировав значение (конечно, в нижнем регистре) рассматриваемого поля сортировки и отсортировав его вместо этого.
case insensitive index с драйвером reactive-mongo? Я использую scala с mongo.
- person oblivion; 31.07.2017
Сортировка работает так же в 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, но теперь она решена. . Подробную документацию см. в этих примечаниях к выпуску. Вы должны использовать collation.
User.find()
.collation({locale: "en" }) //or whatever collation you want
.sort({name:1})
.exec(function(err, users) {
// use your case insensitive sorted results
});
Добавление кода .collation({'locale':'en'}) помогло решить мою проблему.
На данный момент (mongodb 4) вы можете сделать следующее:
оболочка монго:
db.getCollection('users')
.find({})
.collation({'locale':'en'})
.sort({'firstName':1});
мангуста:
Users.find({})
.collation({locale: "en" })
.sort({name: 1})
.exec()
.then(...)
Вот поддерживаемые языки и локали монгодб.
В мангусте: -
Customer.find()
.collation({locale: "en" })
.sort({comapany: 1})
Вот это на Яве. Я смешал без аргументов и первые варианты 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);
}
Если вы хотите отсортировать и вернуть все данные в документе, вы можете добавить document: "$$ROOT"
db.collection.aggregate([
{
$project: {
field: 1,
insensitive: { $toLower: "$field" },
document: "$$ROOT"
}
},
{ $sort: { insensitive: 1 } }
]).toArray()
Пробовал все вышеперечисленное и отвечает Закрепление результата
Ответ-1:
db.collection.aggregate([
{ "$project": {
"field": 1,
"insensitive": { "$toLower": "$field" }
}},
{ "$sort": { "insensitive": 1 } } ])
Совокупный запрос преобразует поле в меньшее, поэтому производительность для больших данных низкая.
Ответ-2:
db.collection.find({}).collation({locale: "en"}).sort({"name":1})
По умолчанию mongo следует правилам кодирования uft-8 (Z имеет более высокий приоритет, чем a), поэтому переопределяет правила, специфичные для языка. Его быстрое сравнение с приведенным выше запросом. Посмотрите официальный документ, чтобы настроить правила.
https://docs.mongodb.com/manual/reference/collation/
Мы решаем эту проблему с помощью функции .sort в массиве JavaScript.
Вот код
function foo() {
let results = collections.find({
_id: _id
}, {
fields: {
'username': 1,
}
}).fetch();
results.sort((a, b)=>{
var nameA = a.username.toUpperCase();
var nameB = b.username.toUpperCase();
if (nameA nameB) {
return 1;
}
return 0;
});
return results;
}