有收藏的:
{"name": "a"},
{"name": "B"},
{"name": "b"},
{"name": "c"},
{"name": "á"},
{"name": "A"}例如。如何在西班牙语中排序它不区分大小写?
我试过了:
var abc = [{"name": "a"}, {"name": "B"}, {"name": "b"}, {"name": "c"}, {"name": "á"}, {"name": "A"}];
for (i in abc) db.abc.save(abc[i]);
db.abc.find({},{"_id":0}).sort({"name":1});输出为:
[
{ "name" : "A" },
{ "name" : "B" },
{ "name" : "a" },
{ "name" : "b" },
{ "name" : "c" },
{ "name" : "á" },
]期望的结果:
[
{ "name" : "a" },
{ "name" : "á" },
{ "name" : "A" },
{ "name" : "b" },
{ "name" : "B" },
{ "name" : "c" }
]发布于 2014-06-04 13:55:46
我知道这是一个老帖子,但我认为不管怎样,回答都会很有用。
您肯定不想在您的应用程序中进行排序,因为这意味着您必须将集合中的所有文档放入内存中,以便对它们进行排序并返回您想要的窗口。如果你的收集量很大,那么这是非常低效的。数据库应该对窗口进行排序并将其返回给您。
但是,您可能会说,MongoDB不支持区域敏感排序。你如何解决这个问题?神奇的是“排序键”的概念。
基本上,假设您有从"a“到"z”的常规英语/拉丁字母表。你要做的就是创建一个从"a“到"01”,从"b“到"02",再到"z”到"26“的排序关键字映射。也就是说,按照该语言的排序顺序将每个字母映射到一个数字,然后将该数字编码为字符串。然后,将要排序的字符串映射到此类型的排序关键字。例如,"abc“将变为"010203”。然后,使用属性的排序关键字将属性添加到文档中,并在属性的名称后面附加区域设置的名称:
{
name: "abc",
name_en: "010203"
}现在,您只需在属性"name_en“上建立索引,就可以在"en”语言中进行排序,并对选择器和范围使用普通的基于英语的MongoDB排序,而不是使用"name“属性。
现在,假设你有另一种疯狂的语言"xx“,其中字母表的顺序是"acb”而不是"abc“。(是的,有些语言会以这种方式扰乱拉丁字母的顺序!)排序关键字如下所示:
{
name: "abc",
name_en: "010203",
name_xx: "010302"
}现在,您所要做的就是在name_en和name_xx上创建索引,并使用常规的MongoDB排序,以便在这些区域设置上正确排序。基本上,额外的属性是在不同地区排序的代理。
那么,您会问,这些映射是从哪里获得的?毕竟,你不是全球化专家,对吧?
如果您使用的是Java、C或C++,有现成的类可以为您完成此映射。在Java语言中,使用标准的排列器类,或者使用icu4j排列器类。如果使用的是C/C++,请使用ICU排序器函数/类的C/C++版本。对于其他语言,除非你能找到一个已经可以做到这一点的库,否则你就有点倒霉了。
这里有一些链接可以帮助你找到它们:
标准的Java库排序器:http://docs.oracle.com/javase/7/docs/api/java/text/Collator.html#getCollationKey(java.lang.String)
C++排序器类:http://icu-project.org/apiref/icu4c/classicu_1_1Collator.html#ae0bc68d37c4a88d1cb731adaa5a85e95
您还可以创建不同的排序键,以便按区域设置不区分大小写进行排序(是的,大小写映射是区域设置敏感的!)和重音不敏感,Unicode变体不敏感,或以上的任意组合。唯一的问题是,现在您有许多与每个可排序属性并行的属性,当您更新基本的"name“属性时,您必须使它们保持同步。这是一个痛苦的你知道什么,但仍然,它比做排序在您的应用程序或业务逻辑层。
同时也要注意游标的范围。例如,在英语中,我们只是忽略字符上的重音。因此,“?”的排序方式与"O“相同,它将出现在"M”到"Z“的范围内。但是,在瑞典语中,重音字符排在"Z“之后。因此,如果你做一个范围"M“- "Z",你将包括一堆以"Ö”开头的记录,这些记录应该是英语的,而不是瑞典语的。
如果对文档的文本属性进行拆分,这也会影响到分片。要注意哪些范围属于哪个分片。最好是在不区分区域设置的东西上进行分片,比如散列。
发布于 2016-11-04 00:15:13
尽管这里的其他答案对于MongoDB版本3.2.x和以前的版本是正确的,但是从3.4.0开始,您可以“为支持排序规则的集合或视图、索引或特定操作指定排序规则”。
发布于 2012-09-19 23:52:49
目前,MongoDB还没有实现排序。
实现Unicode collation standard是解决这个问题的最好方法。
但这会使排序变慢,并使索引变得更大。所以现在,最好在你的应用程序中进行排序。
https://stackoverflow.com/questions/12498156
复制相似问题