如果你有一个双复合索引 {a : 1, b : 1},对我来说,如果你单独查询 b 就不会使用索引(即你不能在您的查询中“跳过”a)。但是,如果您单独查询 a,则会使用该索引。
但是,给定一个三重复合索引 { a : 1, b: 1, c: 1} 我的解释命令显示当您在 a 和 c 上查询时使用该索引(即您可以在查询中“跳过”b)。
Mongo 如何在 ac 的查询中使用 abc 索引,在这种情况下该索引的效率如何?
背景:
我的用例是,有时我想查询 a、b、c,有时我想查询 a、c。现在我应该只在 a、b、c 上创建 1 个索引,还是应该在 a、c 上创建一个,在 a、b、c 上创建一个?
(在a,c,b上创建索引没有意义,因为c是多键索引,选择性好。)
最佳答案
bottom line/tl;dr: 如果 a 和 c 是,索引 b 可以被“跳过”查询是否相等,但不是,例如,c 上的排序。
这是一个很好的问题。不幸的是,我找不到任何可以更详细地权威地回答这个问题的内容。我相信此类查询的性能在过去几年中有所提高,因此我不会相信有关该主题的旧资料。
整个事情非常复杂,因为它取决于索引的选择性以及您是否查询相等、不等和/或排序,所以 explain() 是您唯一的 friend ,但这里有我发现的一些东西:
警告:现在出现的是实验结果、推理和猜测的混合体。我可能把 Kyle 的类比延伸得太远了,我什至可能完全错了(而且很不幸,因为我的测试结果与我的推理大致相符)。
很明显可以使用A的索引,这取决于A的选择性,肯定是很有帮助的。 “跳过”B 可能会很棘手,也可能不会。让我们保持它类似于 Kyle's cookbook example :
French
Beef
...
Chicken
Coq au Vin
Roasted Chicken
Lamb
...
...
如果你现在要我找一些叫做“Chateaubriand”的法国菜,我可以使用索引 A 并且因为我不知道成分,所以必须扫描 中的所有菜>一个。另一方面,我确实知道每个类别中的菜肴列表是通过索引 C 排序的,因此我只需在每个类别中查找以“Cha”开头的字符串成分表。如果有 50 种成分,我将需要 50 次查找而不是一次查找,但这比必须扫描每道法国菜要好得多!
In my experiments, the number was a lot smaller than the number of distinct values in
b: it never seemd to exceed 2. However, I tested this only with a single collection, and it probably has to do with the selectivity of theb-index.
不过,如果你要我给你一份按字母顺序排列的所有法国菜的 list ,我会遇到麻烦。现在 C 上的索引毫无值(value),我必须对所有这些索引列表进行合并排序。为此,我必须扫描每个元素。
这反射(reflect)在我的测试中。下面是一些简化的结果。原始集合有日期时间、整数和字符串,但我想保持简单,所以现在都是整数。
基本上,只有两类查询:nscanned <= 2="" *="">=>limit 的查询,以及必须扫描整个集合(120k 文档)的查询。索引是{a, b, c}:
// fast (range query on c while skipping b)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }});
// slow (sorting)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "c" : -1});
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "b" : -1});
// fast (can sort on c if b included in the query)
> db.Test.find({"a" : 43, "b" : 7887, "c" : { $lte : 45454 }}).sort({ "c" : -1});
// fast (older tutorials claim this is slow)
> db.Test.find({"a" : {$gte : 43}, "c" : { $lte : 45454 }});
您的里程会有所不同。
关于mongodb - Mongo 三重复合指数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11053201/
我遇到了同样的问题here对于python,但对于ruby。我需要输出这样一个小数字:0.00001,而不是1e-5。有关我的特定问题的更多信息,我正在使用f.write("Mynumber:"+small_number.to_s+"\n")输出到一个文件对于我的问题,准确性不是什么大问题,所以只做一个if语句来检查是否small_number那么更通用的方法是什么? 最佳答案 f.printf"Mynumber:%.5f\n",small_number您可以将.5(小数点右侧5位数字)替换为您喜欢的任何特定格式大小,例如,%8
ZedShaw的LearnRubytheHardWay第9章使用三重双引号:puts"""There'ssomethinggoingonhere.Withthethreedouble-quotes.We'llbeabletotypeasmuchaswelike.Even4linesifwewant,or5,or6."""我试着用单双引号写同样的东西,它似乎工作正常。我不明白三引号和单双引号之间的区别。我错过了什么吗? 最佳答案 我不知道他为什么在他的书中使用三重双引号。它们没什么特别的,一个双引号就可以了。这是ruby的一个鲜为
我刚刚注意到Array没有覆盖三重等号方法===,这有时被称为大小写相等方法。x=2casexwhen[1,2,3]then"match"else"nomatch"end#=>"nomatch"而范围运算符则:x=2casexwhen1..3then"match"else"nomatch"end#=>"match"但是,您可以为数组做一个变通办法:x=2casexwhen*[1,2,3]then"match"else"nomatch"end#=>"match"知道为什么会这样吗?是不是因为x更可能是一个实际的数组而不是一个范围,并且数组覆盖===意味着普通的相等性不会匹配?#Thisi
我只是在做一些与大学相关的Diffie-Hellman练习,并尝试使用ruby。遗憾的是,ruby似乎无法处理大指数:warning:ina**b,bmaybetoobigNaN[...]有什么办法吗?(例如,特殊的数学课或类似的东西?)附注这是有问题的代码:generator=7789prime=1017473alice_secret=415492bob_secret=725193putsfrom_alice_to_bob=(generator**alice_secret)%primeputsfrom_bob_to_alice=(generator**bob_secret)%pr
我正在使用UbuntuServer10,Ruby1.9.2当我尝试要求'mongo'时它给我这个错误:irb(main):001:0>require'mongo'LoadError:nosuchfiletoload--opensslfrom/usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in`require'from/usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in`require'from/usr/local/lib
我有一个如下所示的User模型:classUser数据库中的users表有两个外键organization_id和department_id。如何使这两列成为复合主键?到目前为止,我在网上看到了两种方法:选项1使用composite_primary_keysgem选项2使用如下方式为两列中的每一列添加索引:add_index:users,[:organization_id,:department_id],unique:true我的问题在users表中唯一标识一行的最佳方法是什么,其中一行必须按顺序具有department_id和organization_id被唯一识别?索引两列和简单地
我可以在一个Rails应用程序中同时使用MongoDB和PostgreSQL吗?具体来说,我最终会想要使用像MongoHQ这样的东西。到目前为止,我未能在实验中进行这项工作。令我担心的是,MongoDB文档特别指出我必须禁用ActiveRecord。任何建议将不胜感激。 最佳答案 您无需禁用ActiveRecord即可使用MongoDB。查看Mongoid只需将gem加上任何模型与您现有的任何ActiveRecord模型一起添加。您应该注意到MongoHQ只是MongoDB的托管服务,可以与任何对象文档映射器(ODM)一起使用。更多
给定以下资源定义:map.resources:posts,:except=>[:show]map.post'/:year/:month/:slug,:controller=>:posts,:action=>:show我可以让url_for为我工作,使用这个语法:'2010',:month=>'02',:slug=>'test')%>但是有没有办法让它工作呢?目前它抛出这个错误:Noroutematches{:year=>#,:controller=>"posts",:action=>"show"}显然它将@post对象传递给第一个路由参数(看起来像一个Rails错误...)。但是我可以
我必须在mongoid模型中添加几个字段,我知道MongoDB没有迁移,但如果我继续而不删除数据库,使rails完全“重新生成”数据库,它不会显示或使用新的领域!去这里最好的方法是什么?有比删除/重新打开mongodb更软的东西吗?提前致谢卢卡 最佳答案 一般来说,应该可以在运行时用新字段更新旧文档。MongoDB中不需要迁移。您可能想编写rake任务以使用新字段和默认值更新旧文档。您可以通过检查那些默认值为nil的新字段来找到这些文档。更新简单风格:如果您使用默认值定义一个新字段,只要您设置了一个新值,就应该始终使用该值:应用程序
我如何从Ruby代码连接到mongodb? 最佳答案 首先,您必须安装MongoDbgem:geminstallmongo然后运行代码:require'rubygems'#notnecessaryforRuby1.9require'mongo'db=Mongo::Connection.new.db("mydb")#ORdb=Mongo::Connection.new("localhost").db("mydb")#ORdb=Mongo::Connection.new("localhost",27017).db("mydb")