[英]Case insensitive sorting in MongoDB
How can I sort a MongoDB collection by a given field, case-insensitively?如何按给定字段对 MongoDB 集合进行排序,不区分大小写? By default, I get AZ before az.默认情况下,我在 az 之前获得 AZ。
Update: As of now mongodb have case insensitive indexes:更新:截至目前 mongodb 有不区分大小写的索引:
Users.find({})
.collation({locale: "en" })
.sort({name: 1})
.exec()
.then(...)
shell:贝壳:
db.getCollection('users')
.find({})
.collation({'locale':'en'})
.sort({'firstName':1})
Update: This answer is out of date, 3.4 will have case insensitive indexes.更新:此答案已过时,3.4 将具有不区分大小写的索引。 Look to the JIRA for more information https://jira.mongodb.org/browse/SERVER-90查看 JIRA 以获取更多信息https://jira.mongodb.org/browse/SERVER-90
Unfortunately MongoDB does not yet have case insensitive indexes: https://jira.mongodb.org/browse/SERVER-90 and the task has been pushed back.不幸的是,MongoDB 还没有不区分大小写的索引: https : //jira.mongodb.org/browse/SERVER-90并且该任务已被推迟。
This means the only way to sort case insensitive currently is to actually create a specific "lower cased" field, copying the value (lower cased of course) of the sort field in question and sorting on that instead.这意味着当前排序不区分大小写的唯一方法是实际创建一个特定的“小写”字段,复制有问题的排序字段的值(当然是小写)并对其进行排序。
Sorting does work like that in MongoDB but you can do this on the fly with aggregate:排序确实像在 MongoDB 中那样工作,但您可以使用聚合动态执行此操作:
Take the following data:取以下数据:
{ "field" : "BBB" }
{ "field" : "aaa" }
{ "field" : "AAA" }
So with the following statement:所以用下面的语句:
db.collection.aggregate([
{ "$project": {
"field": 1,
"insensitive": { "$toLower": "$field" }
}},
{ "$sort": { "insensitive": 1 } }
])
Would produce results like:会产生如下结果:
{
"field" : "aaa",
"insensitive" : "aaa"
},
{
"field" : "AAA",
"insensitive" : "aaa"
},
{
"field" : "BBB",
"insensitive" : "bbb"
}
The actual order of insertion would be maintained for any values resulting in the same key when converted.对于在转换时产生相同键的任何值,将保持插入的实际顺序。
This has been an issue for quite a long time on MongoDB JIRA, but it is solved now.这个问题在 MongoDB JIRA 上已经存在很长时间了,但现在已经解决了。 Take a look at this release notes for detailed documentation .有关详细文档,请查看此发行说明。 You should use collation
.您应该使用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'})
有助于解决我的问题。
As of now (mongodb 4), you can do the following:截至目前(mongodb 4),您可以执行以下操作:
mongo shell:蒙戈外壳:
db.getCollection('users')
.find({})
.collation({'locale':'en'})
.sort({'firstName':1});
mongoose:猫鼬:
Users.find({})
.collation({locale: "en" })
.sort({name: 1})
.exec()
.then(...)
Here are supported languages and locales by mongodb.以下是 mongodb 支持的语言和区域设置。
In Mongoose:-在猫鼬中:-
Customer.find()
.collation({locale: "en" })
.sort({comapany: 1})
Here it is in Java.这是在Java中。 I mixed no-args and first key-val variants of BasicDBObject
just for variety我混合了无参数和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);
}
If you want to sort and return all data in a document, you can add document: "$$ROOT"
如果要对文档中的所有数据进行排序并返回,可以添加document: "$$ROOT"
db.collection.aggregate([
{
$project: {
field: 1,
insensitive: { $toLower: "$field" },
document: "$$ROOT"
}
},
{ $sort: { insensitive: 1 } }
]).toArray()
Tried all the above and answers Consolidating the result尝试了以上所有并回答巩固结果
Answer-1:答案-1:
db.collection.aggregate([
{ "$project": {
"field": 1,
"insensitive": { "$toLower": "$field" }
}},
{ "$sort": { "insensitive": 1 } } ])
Aggregate query converts the field into lower, So performance is low for large data.聚合查询将字段转换为较低,因此对于大数据性能较低。
Answer-2:答案 2:
db.collection.find({}).collation({locale: "en"}).sort({"name":1})
By default mongo follows uft-8 encoding(Z has high piriority then a) rules ,So overriding with language-specific rules.默认情况下,mongo 遵循 uft-8 编码(Z 具有高优先级)规则,因此覆盖特定于语言的规则。 Its fast compare to above query Look into an official document to customize rules与上面的查询相比,它的快速比较 查看官方文档以自定义规则
https://docs.mongodb.com/manual/reference/collation/ https://docs.mongodb.com/manual/reference/collation/
We solve this problem with the help of .sort function in JavaScript array我们借助 JavaScript 数组中的 .sort 函数解决了这个问题
Here is the code这是代码
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; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.