MongoDB 中的不区分大小写排序

如何按给定的字段对 MongoDB 集合排序,不区分大小写? 默认情况下,在 A-Z 之前是 A-Z。

59391 次浏览

更新: 到目前为止,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和任务已被推回。

这意味着当前排序不区分大小写的唯一方法是实际创建一个特定的“小写”字段,复制有问题的 sort 字段的值(当然是小写) ,然后对它进行排序。

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

对于在转换时产生相同键的任何值,将维护实际的插入顺序。

在 Java 中,我混合了 BasicDBObject的 no-args 和 first key-val 变体,只是为了多样化

        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);
}

这在 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
});

我们利用 JavaScript 数组中的. sort 函数来解决这个问题

这是密码



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


从现在开始(mongodb 4) ,您可以执行以下操作:

芒果壳:

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

猫鼬:

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

这是蒙哥布的 支持的语言和地区

添加代码 .collation({'locale':'en'})有助于解决我的问题。

在猫鼬:-

Customer.find()
.collation({locale: "en" })
.sort({comapany: 1})

试了以上所有的方法和答案 巩固结果

答案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/

如果要对文档中的所有数据进行排序并返回,可以添加 document: "$$ROOT"

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