对于一个作为计数器的字段,即值会随着时间的推移而变化,将用于返回有序的实体(将针对过滤后的实体根据该字段进行排序),我们是否应该为该字段建立索引?
最佳答案
这还不是很清楚,但我认为问题是在频繁更新的字段上创建索引的缺点是否会超过对该字段进行快速查询和排序的好处。您还暗示您的查询将在不同的字段上进行过滤,然后您希望在该字段上进行排序。请随意详细说明您的确切用例。
我想你想要的是这样的:
db.test.save({filter: "stuff", count: "1"});
db.test.save({filter: "stuff", count: "3"});
db.test.save({filter: "stuff", count: "2"});
db.test.save({filter: "notstuff", count: "2"});
db.test.save({filter: "notstuff", count: "2"});
然后是这样的索引:
db.test.ensureIndex({filter:1, count:1});
然后是这样的查询:
db.test.find({filter:"stuff"}).sort({count:1});
{ "_id" : ObjectId("4f24353eef88b8b53a20fdf5"), "filter" : "stuff", "count" : "1" }
{ "_id" : ObjectId("4f24353eef88b8b53a20fdf7"), "filter" : "stuff", "count" : "2" }
{ "_id" : ObjectId("4f24353eef88b8b53a20fdf6"), "filter" : "stuff", "count" : "3" }
其中使用了 btree:
db.test.find({filter:"stuff"}).sort({count:1}).explain();
{
"cursor" : "BtreeCursor filter_1_count_1",
"nscanned" : 3,
"nscannedObjects" : 3,
...
现在,这实际上可能取决于您需要返回多少结果。如果只有几个结果,您可能可以在没有索引的情况下对字段进行排序,这将提高更新性能。我想我真的会做一些测试,因为我很好奇。我会稍后更新。
更新 我编写此基准测试是为了显示按索引排序与不按索引排序与更新索引计数字段与不更新之间的区别。完整代码在这里:https://gist.github.com/1696041
它插入 700K 和 7M 文档(以获得一些多样性),分为 7 个“过滤器”。然后它随机选择一个文档来增加 1M 次的计数。每个过滤器 100 万个文档太大,无法无限制地排序,因此展示该部分如何工作的唯一方法是设置一个限制。
结论和预想的一样。当上面有索引时,更新计数字段需要更长的时间(在这个测试中几乎是原来的两倍——但两倍的时间仍然相当快)。但是查询起来要快得多。您必须决定哪个对您更重要。
输出在这里(在我的带 SSD 的 macbook pro 上运行):
> bench();
benchmarking with index on {filter,data}, 700K docs
initialInsert of 700000 done in: 58304ms, 0.08329142857142857ms per insert
updateCounts 1000000 times done in: 103915ms, 0.103915ms per update
explain find({filter:"abcd"}).sort({count:-1}):
cursor: BtreeCursor filter_1_data_1
nscanned: 100000
scanAndOrder: true
millis: 1235
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_data_1
nscanned: 100000
scanAndOrder: true
millis: 614
benchmarking with index on {filter,data} and {filter, count}, 700k docs
initialInsert of 700000 done in: 72108ms, 0.10301142857142857ms per insert
updateCounts 1000000 times done in: 202778ms, 0.202778ms per update
explain find({filter:"abcd"}).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 100000
scanAndOrder: undefined
millis: 139
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 100
scanAndOrder: undefined
millis: 0
benchmarking with index on {filter,data}, 7M docs
initialInsert of 7000000 done in: 616701ms, 0.08810014285714286ms per insert
updateCounts 1000000 times done in: 134655ms, 0.134655ms per update
explain find({filter:"abcd"}).sort({count:-1}):
***too big to sort without limit!***
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_data_1
nscanned: 1000000
scanAndOrder: true
millis: 6396
benchmarking with index on {filter,data} and {filter, count}, 7M docs
initialInsert of 7000000 done in: 891556ms, 0.12736514285714284ms per insert
updateCounts 1000000 times done in: 280885ms, 0.280885ms per update
explain find({filter:"abcd"}).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 1000000
scanAndOrder: undefined
millis: 1337
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 100
scanAndOrder: undefined
millis: 0
关于mongodb - 针对计数器字段构建索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9047128/
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']
在编写Ruby(客户端脚本)时,我看到了三种构建更长字符串的方法,包括行尾,所有这些对我来说“闻起来”有点难看。有没有更干净、更好的方法?变量递增。ifrender_quote?quote="NowthatthereistheTec-9,acrappyspraygunfromSouthMiami."quote+="ThisgunisadvertisedasthemostpopularguninAmericancrime.Doyoubelievethatshit?"quote+="Itactuallysaysthatinthelittlebookthatcomeswithit:themo
我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm
我发现自己需要这个。假设cart是一个包含用户列表的模型。defindex_of_itemcart.users.each_with_indexdo|u,i|ifu==current_userreturniendend获取此类关联索引的更简单方法是什么? 最佳答案 indexArray上的方法与您的index_of_item方法相同,例如cart.users.index(current_user)返回数组中第一个对象的索引==给obj。如果未找到匹配项,则返回nil。 关于ruby-on-
我几天前在我的rubyonrails2.3.2上安装了Sphinx和Thinking-Sphinx,基本搜索效果很好。这意味着,没有任何条件。现在,我想用一些条件过滤搜索。我有公告模型,索引如下所示:define_indexdoindexestitle,:as=>:title,:sortable=>trueindexesdescription,:as=>:description,:sortable=>trueend也许我错了,但我注意到只有当我将:sortable=>true语法添加到这些属性时,我才能将它们用作搜索条件。否则它找不到任何东西。现在,我还在使用acts_as_tag
假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案