Mongoid在单个查询中推送新的嵌入式文档

提诺

我们使用蒙古语来存储用户分数:

class UserScore
  include Mongoid::Document

  field :user_id, type: Integer
  field :points,  type: Integer, default: 0
  embeds_many :activities
end

我们通过将用户的活动收集在称为活动的嵌入式文档中来跟踪用户的活动。随着活动数量的增加,如果mongoid将加载所有嵌入式文档,则访问user.user_score的时间也会增加。如果我们添加一个新活动,它将始终导致两个查询:

UserScore.where( user_id: user.id ).first.activities << Activity.new(values)

一个查询找到UserScores,一个查询推送。

MOPED: 127.0.0.1:27017 QUERY        database=development collection=user_scores selector={"$query"=>{"user_id"=>121920}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil 
(192.1866ms)
MOPED: 127.0.0.1:27017 UPDATE       database=development collection=user_scores selector={"_id"=>"53cfe22869d256929d000139"} update={"$push"=>{"activities"=>{"_id"=>"54ed824d4c5c34f157000011", "points"=>50, "created_at"=>2015-02-25 08:05:33 UTC}}} flags=[] 
(0.5269ms)

find-query不是必需的,因为我们还可以通过使用助力车来推送新的嵌入式文档,如下所示:

Mongoid::Sessions.default[:user_scores].find(user_id: user.id).update('$push' => {'activities' => values)})

MOPED: 127.0.0.1:27017 UPDATE       database=development collection=user_scores selector={:user_id=>125721} update={"$push"=>{"activities"=>{:points=>50, "_id"=>"54ed80224c5c34f157000007", :created_at=>2015-02-25 07:56:18 UTC}}} flags=[] 
(0.5438ms)

有没有办法在蒙古族中实现这一目标?我们之所以要使用蒙古型,是因为我们希望将新活动作为红宝石对象进行处理。同样,通过推入这样的值,活动文档将缺少我们必须在应用程序中创建的_id和created_at字段,这会导致代码更丑陋。

我们使用Mongoid 3.1.6。是否可能在以后的版本中添加或将添加某种延迟加载?

更新:

我们模拟用户和用户得分之间的关​​系,因为用户存储在mysql数据库中:

class User
  def user_score
    UserScore.where(user_id: self.id).first
  end
end

所以我们不能使用这样的关系

user.user_score << Activity.new(values)

没有相同的结果。

提诺

经过更多研究后,似乎没有其他方法可以替代我在问题中描述的方法。Mongoid始终使用嵌入式文档加载整个文档。如果使用only(),则无法操作文档。

我还注意到,如果您有几千个嵌入式文档,则将数组推入数组的效率会降低。解决这两个问题的方法是将嵌入的文档移到单独的集合中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章