目前我正在做以下事情:
responses = Response.where(user_id: current_user.uid)
qids = []
responses.each { |r| qids << r._id}
return qids
有更好的方法吗?
答案 0 :(得分:2)
使用.only()
检索更少的数据。
quids = Response.only(:_id).where(user_id: current_user.uid).map(&:_id)
答案 1 :(得分:0)
Response.where(user_id: current_user.uid).map { |r| r._id }
这有点像惯用语。
就mongoid而言,mongoid提供的唯一“映射”类型功能是自定义map-reduce滤镜。您可以查看documentation。
在这种情况下,编写这样的过滤器对您没有好处。您正在加载整个数据集(延迟加载没有帮助)并且您没有减少任何内容。
答案 2 :(得分:0)
如果您想获取结果集中唯一的id或内容,那么它在功能上等同于使用distinct方法。这样你就可以保存映射操作,而且它看起来要快得多(测试以及为什么你应该采取一些预防措施来解决它们的问题)。
Response.where(user_id: current_user.uid).distinct(:_id)
因此,如果您想获得非独特的东西,并且出于某种原因想要获得重复的结果,那么只能使用它。即如果您的回复可能会被喜欢,并且您想获得所有喜欢的数组(假设您想要计算一些有关喜欢的统计数据):
Response.where(user_id: current_user.uid).map { |r| r.likes }
这是一些随机测试,但是对于更值得信赖的结果,应该使用大型数据库提交测试,而不是重复操作。我的意思是,我知道可以有任何类型的优化来重复重复相同的查询(显然地图不能有任何这样的优化)。
Benchmark.measure { 1000.times { Organization.where(:event_labels.ne =[]).map(&:_id) } }
=> 6.320000 0.290000 6.610000 ( 6.871498)
Benchmark.measure { 1000.times { Organization.where(:event_labels.ne => []).only(:_id).map(&:_id) } }
=> 5.490000 0.140000 5.630000 ( 5.981122)
Benchmark.measure { 1000.times { Organization.where(:event_labels.ne => []).distinct(:_id) } }
=> 0.570000 0.020000 0.590000 ( 0.773239)
Benchmark.measure { 1000.times { Organization.where(:event_labels.ne => []).only(:_id) } }
=> 0.140000 0.000000 0.140000 ( 0.141278)
Benchmark.measure { 1000.times { Organization.where(:event_labels.ne => []) } }
=> 0.070000 0.000000 0.070000 ( 0.069482)
在没有map
的情况下执行only
需要更长的时间,因此使用only
是有益的。虽然使用它似乎实际上略微损害了性能,如果你根本不做map
,但拥有较少的数据似乎会使map
运行得更快一些。无论如何,根据这个测试,似乎distinct
在所有指标(用户,系统,总数,实际)上比使用only
和map
组合快10倍,尽管它比使用only
而不使用map
。