目前我正在做以下事情:
responses = Response.where(user_id: current_user.uid)
qids = []
responses.each { |r| qids << r._id}
return qids
有更好的方法吗?
用于.only()
检索较少的数据。
quids = Response.only(:_id).where(user_id: current_user.uid).map(&:_id)
Response.where(user_id: current_user.uid).map { |r| r._id }
这有点惯用语。
就 mongoid 而言,mongoid 提供的唯一“映射”类型功能是自定义 map-reduce 过滤器。您可以查看文档。
在这种情况下,编写这样的过滤器不会对您有利。您正在加载整个数据集(延迟加载没有帮助)并且您没有减少任何内容。
如果您想获取 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
运行速度更快一些。无论如何,根据这个测试,它在所有指标(用户、系统、总数、真实)上似乎比使用and组合distinct
快大约 10 倍,尽管它比不使用.only
map
only
map