设为首页 收藏本站
查看: 864|回复: 0

[经验分享] Ruby操作MongoDB(进阶七)-排序规则Collations

[复制链接]

尚未签到

发表于 2018-10-25 08:08:38 | 显示全部楼层 |阅读模式
  本篇博文从三个方面进行排序规则Collations的讲解。其中包括概览,使用方式和支持排序的操作。首先我们对排序规则进行一个概览性的介绍

  •   排序规则概览
  排序规则为特定语言习惯中的字符串比较提供一套规则,例如,在加拿大法语中,给定词汇的最后一个重音节决定了其排序顺序。
  考虑下述法语词汇:
cote < coté < cte < cté  使用加拿大法语排序规则,得到如下排序结果
cote < cte < coté < cté  如果没有指定排序规则,MongoDB使用简单的二进制比较排序。按照这样的规则,上述单词的排序结果是
cote < coté < cte < cté  2. 排序规则的使用
  创建集合和创建索引时,我们可以指定默认的排序规则,也可以为集合及聚合的CRUD操作指定排序规则。对于支持排序规则的操作,如果没有指定不同的排序规则,MongoDB会使用默认的排序规则。
  排序规则参数
'collation' => {  
   'locale' => ,
  
   'caseLevel' => ,
  
   'caseFirst' => ,
  
   'strength' => ,
  
   'numericOrdering' => ,
  
   'alternate' => ,
  
   'maxVariable' => ,
  
   'normalization' => ,
  
   'backwards' => }
  唯一一个必须设定的参数是locale。服务器会将该参数转换为一个 ICU format locale>en_US 代表美式英语,fr_CA 代表加拿大法语。完整的参数值可以查看 MongoDB manual entry。
  2.1 为集合指定排序规则
  下面的实例在test数据库上创建了一个contacts的集合,并且给其分配了默认的locale值为fr_CA排序规则。创建集合的时候指定一个排序规则,确保了集合contacts上包含查询在内的所有操作都会使用fr_CA排序规则,除非操作指定了特定的排序规则。新建集合上的索引也会继承默认的排序规则,除非创建索引时指定了其他的排序规则。
client=Mongo::Client.new(['127.0.0.1:27017'],:database=>'test')  
client[:contacts,{"collation"=>{"locale"=>"fr_CA"}}]
  2.2 为索引指定排序规则
  为索引指定排序规则,可以在创建索引的时候指定collation参数,下面的实例在名为address_book集合的name字段域(first_name)上创建索引,并设定为唯一索引,同时设定了默认的排序规则的locale属性为en_US。
client=Mongo::Client.new(['127.0.0.1:27017'],:database=>'test')  
client[:address_book].indexes.create_one({"first_name"=>1},
  
                                          "unique"=>true,
  
                                          "collation"=>{ "locale" => "en_US" }
  
                                          )
  为了使用该索引,你必须确保你所用的查询中也指定了这种排序规则,下面的查询使用上面定义的索引
client[:address_book].find({"first_name"=>"Adam"},  
                            "collation"=>{ "locale" => "en_US" })
  而下面的这种查询就无法使用上面定义的索引,第一种情况是没有定义排序集合collation属性;第二种情况是排序集合上多指定了一个strength属性
client[:address_book].find({"first_name"=>"Adam"})  
client[:address_book].find({"first_name"=>"Adam"},
  
                            "collation"=>{"locale"=>"en_US","strength"=>2})
  3 支持排序规则的操作
  MongoDB数据库中,所有的查询,更新和删除方法均支持排序规则。下面列出了一些常用方法:
  3.1 find和sort方法
  在查询结果和排序的时候,单个查询可以指定排序规则。下面的查询排序的例子,通过将collation的locale属性设置为de,设定该查询排序使用基于德语的排序规则
client=Mongo::Client.new(['127.0.0.1:27017'],:database=>"test")  
client[:contacts].find({"city"=>"New York"},{"collation"=>{"locale"=>"de"}}).sort({"name"=>1})
  3.2 find_one_and_update方法
  假设一个集合names中包含了以下文档:
{ "_id" : 1, "first_name" : "Hans" }  
{ "_id" : 2, "first_name" : "Gunter" }
  
{ "_id" : 3, "first_name" : "Günter" }
  
{ "_id" : 4, "first_name" : "Jürgen" }
  下面的find_one_and_update操作没有指定排序规则:
client=Mongo::Client.new(['127.0.0.1:27017'],:database=>'test')  
doc=client[:names].find_one_and_update({"first_name"=>{"$lt"=>"Gunter"}},{"$set"=>{"verified"=>true}})
  由于Gunter 是集合文档中的第一个词汇,所以上述查询结果为空,也不会更新任何文档。同样的find_one_and_update方法,但是指定了排序组合,locle属性设置了de@collation=phonebook.
  对于区分专有名词和其他词汇区别的语言,有些locale属性包含collation=phonebook可选参数。设定了collation=phonebook的排序规则,有元音变音的字符会在没有元音变音字符之前返回。
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test")  
doc = client[:names].find_one_and_update( { "first_name" => { "$lt" => "Gunter" } },
  
  { "$set" => { "verified" => true } }, { "collation" => { "locale" => "de@collation=phonebook" },:return_document => :after } )
  上述操作后的结果如下:
{ "_id" => 3, "first_name" => "Günter", "verified" => true }  3.2 find_one_and_update方法
  通过将numericOrdering 参数设置true可以使用比较数字型字符串,比较的方式就是使用字符串对应的数值。例如numbers集合包含下面的文档:
{ "_id" : 1, "a" : "16" }  
{ "_id" : 2, "a" : "84" }
  
{ "_id" : 3, "a" : "179" }
  下面的例子是找到一个包含数字型字段的且数值大于100的文档,并且删除它
docs=find_one_and_deletes({"a"=>{"$gt"=>100}},{"collation"=>{"locale"=>"end","numericOrdering"=>true}})  执行了上述操作后,文档中的
{ "_id" : 1, "a" : "16" }  
{ "_id" : 2, "a" : "84" }
  仍然存在,但是
{ "_id" : 3, "a" : "179" }  被删除了。
  但是如果同样的操作,却不使用排序规则。那么服务器会找到a的词汇值大于100的第一个文档并且删除它。
  这时,文档中的第一个被删除了。查询后的结果如下:
{ "_id" : 2, "a" : "84" }  
{ "_id" : 3, "a" : "179" }
  3.3 多条删除delete_many()
  Ruby驱动中所有的批量操作都可以使用排序规则参数。假设集合recipes 包含下面的文档:
{ "_id" : 1, "dish" : "veggie empanadas", "cuisine" : "Spanish" }  
{ "_id" : 2, "dish" : "beef bourgignon", "cuisine" : "French" }
  
{ "_id" : 3, "dish" : "chicken molé", "cuisine" : "Mexican" }
  
{ "_id" : 4, "dish" : "chicken paillard", "cuisine" : "french" }
  
{ "_id" : 5, "dish" : "pozole verde", "cuisine" : "Mexican" }
  设置collation中的strength 为1或者2,可以让服务器在查询过滤器运行时忽略大小写,下面的案例使用不区分大小写的查询过滤器来进行cuisine 字段匹配了French的文档的删除操作。
client=Mongo::Cient.new(['127.0.0.1:27017'],:database=>'test')  
receipes=client[:receipes]
  
docs=delete_many({"cusine"=>"French"},{"collation"=>{"locale"=>"en_US","strength"=>1}})
  执行上述指令后,_id值为2和4的文档被删除掉了。
  3.4 聚合Aggregation
  在集合上进行聚合操作,需要设置collation的aggregation字段。下面的聚合实例使用了一个名为names的集合并且将first_name域分到一组,计算了每个分组的结果文档数,而且通过German phonebook进行排序。
aggregation=names.aggregate(  
[
  
{"$group"=>{"$_id"=>"$first_name","name_count"=>{"$sum"=>1}}},
  
{"$sort"=>{"$id"=>1}}
  
],{"collection"=>{"locale"=>"de@collation=phonebook"}})
  
aggregation.each do |doc|
  
  p doc
  
end



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-626113-1-1.html 上篇帖子: Ruby操作MongoDB(进阶六)-索引Indexing 下篇帖子: Ruby操作MongoDB(进阶八)-聚合操作Aggregation
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表