使用Mongoid/mongodb提取,建模和更改数据模型 [英] Extracting, modelling and changing data model, with mongoid/mongodb

查看:171
本文介绍了使用Mongoid/mongodb提取,建模和更改数据模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种更好的方法,如果可能的话,使用令人惊奇的 mongoid ODM 来操作现有的mondodb数据模型.驱动程序.

I'm looking for a better way, if it's possible, for manipulating an existing mondodb datamodel using amazing mongoid ODM driver.

假设您有一个嵌入一对多的数据模型,例如以下:

Suppose you have an embedded one to many data model like the following :

class User
  include Mongoid::Document

  field :nickname
  embeds_many :watchlists
end

class Watchlist
 include Mongoid::Document

 field :html_url
 field :description
 field :tags_array, type: Array
 embedded_in :user
end

现在,对于所有用户,您只希望提取每个监视列表的一部分,只要且仅当它具有

Now, for all users you want to extract just a part of every watchlist, if and only if, it has

tags_array == ["ruby", "web", "framework"]

仅返回几个字段(不是整个监视列表文档):

having back just few fields (not the entire watchlist doc):

  1. 监视列表的html_url内容
  2. 监视列表的描述内容

  1. 相关的父母昵称(User.nickname)

我尝试过这样的事情:

1.9.2p290 :574 > Competitor = Struct.new(:html_url, :description, :user)
=> #<Class:0xed08de8>
1.9.2p290 :575 > competitors = []
=> []
1.9.2p290 :576 >  User.all.map do |user|
1.9.2p290 :577 >     user.watchlists.all.map do |wl|
1.9.2p290 :578 >           if wl.tags_array == ["ruby", "web", "framework"]
1.9.2p290 :579?>                 competitors << Competitor.new(wl.html_url, wl.description, wl.user.nickname)
1.9.2p290 :580?>           end
1.9.2p290 :581?>     end
1.9.2p290 :582?> end

这里有一些提示:

1.9.2p290 :585 > competitors
=> [#<struct html_url="https://github.com/rails/rails", description="Ruby on Rails", user="lgs">, #<struct html_url="https://github.com/sinatra/sinatra", description="Classy web-development dressed in a DSL (official / canonical repo)", user="lgs">]
1.9.2p290 :586 > competitors.size
=> 2
1.9.2p290 :599 > competitors[0][:html_url]
=> "https://github.com/rails/rails"
1.9.2p290 :600 > competitors[1][:html_url]
=> "https://github.com/sinatra/sinatra"
1.9.2p290 :601 >

但是我想知道,是否有更好,更聪明,更快,有效,有效,美观(或只是不同" )的方式来实现此目的...

But I wonder, if there are better, smarter, faster, efficient, effective, aesthetic ( or just "different" ) way, of doing that ...

推荐答案

您要做两件事:

  • 使用db查询过滤用户,而不是在应用程序中过滤
  • 仅从数据库中获取您需要的字段,而不是整个用户对象(假设用户中还有其他内容,为简便起见,在此省略)

  • Filter the users with db query instead of filtering in application
  • only fetch fields you need from db, rather than the whole user objects(assuming you have some other stuff in user, which you omitted here for brevity)

Competitor = Struct.new(:html_url, :description, :user)
competitors = []
User.where('watchlists.tags_array' => %w[ruby web framework]).
    only(:nickname, :watchlists).each do |u|
  u.watchlists.where(:tags_array => %w[ruby web framework]).each do |wl|
    competitors << Competitor.new(wl.html_url, wl.description, u.nickname)
  end
end

PS:可能您不想在User.all上使用map,如果您有大量用户文档,它将需要大量内存.另外,您不是在使用映射的用户,而是自己在competitors数组中收集结果,因此each应该可以正常工作.

PS: Probably you do not want to use map on User.all, it will require a lot of memory if you have lots of heavy user documents. Also, you are not using the mapped users, but instead collecting results in the competitors array yourself, so each should work just fine.

这篇关于使用Mongoid/mongodb提取,建模和更改数据模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆