【问题标题】:mongoid - how to query by embedded objectmongoid - 如何通过嵌入对象查询
【发布时间】:2012-03-19 07:23:50
【问题描述】:

我有以下型号:

class User
  include Mongoid::Document
  store_in :users

  field :full_name,   :type => String
end

class Message
  include Mongoid::Document

  embeds_one :sender, :class_name => "User"

  field :text,        :type => String
end

我想将UserMessage 存储在单独的独立集合中,以便可以直接查询它们,并且我想在每个消息条目中拥有sender 的用户副本。我的模型是否适合这种请求?

当我有一个用户user 的实例时,我如何查询sender = user 的消息?

我试过了: Message.where(:sender => user) Message.where('sender.id' => user.id) 两者都不起作用。

只有Message.where('sender.full_name' => user.full_name) 有效,但我不想在需要使用 id 字段时依赖文本字段。

最好的方法是什么?

我如何保存消息/用户:

user = User.new
user.full_name = 'larry'
user.save

m = Message.new(:text => 'a text message')
m.sender = user
m.save

它会生成数据库:

> db.users.find({ 'full_name' : 'larry'})
> db.messages.find({})[0]
{
        "_id" : ObjectId("4f66e5c10364392f7ccd4d74"),
        "text" : "a text message",
        "sender" : {
                "_id" : ObjectId("4f62e0af03642b3fb54f82b0"),
                "full_name" : "larry"
        }
}

【问题讨论】:

  • 没错,穆。您可以将其转换为答案。但是我还是觉得有点迷茫。因为我一直觉得Message.where(:sender => user)应该是这样做的方式。

标签: mongodb mongoid


【解决方案1】:

就像 Jordan Durran(Mongoid 首席开发人员)在 Google Mongoid 小组中的解释:http://groups.google.com/group/mongoid/browse_thread/thread/04e06a8582dbeced#

如果您想嵌入用户,您将需要一个单独的模型 消息内的数据。当像这样非规范化时,我通常 命名空间之一,并创建一个具有公共字段的模块 两者都包括 - 也许在你的情况下你可以称之为发件人?

class Sender 
  include Mongoid::Document 
  include UserProperties 

  class << self 
    def from_user(user) 
      Sender.new(user.attributes) 
    end 
  end 
end 

class User 
  include Mongoid::Document 
  include UserProperties 
end 

module UserProperties 
  extend ActiveSupport::Concern 
  included do 
    field :full_name, type: String 
  end 
end 

class Message 
  include Mongoid::Document 
  embeds_one :sender 
end 

您也不需要 User 上的 :store_in 宏 - 默认情况下它的名称 将是“用户”。

【讨论】:

  • 太棒了!虽然这实际上是我在 googlegroup 中发布的同一个问题,但这些天我忘了回去检查它:P。可悲的是,我可能不得不再次调整我的模型。前几天我已经退回使用参考。
  • 是的,我关注了 google 组,这就是为什么我将 Durran 的答案粘贴在这里。如果您在 google group 上做一个问题,您可以链接您的 SO question is you do before.
  • 是的,下次我会这样做的。
【解决方案2】:

你不能做你做的事。

您的用户文档保存在他的一个集合中,因为您使用了store_in 方法。然后您尝试将其保存在其他文档中 (Message)

如果你真的想要 2 个集合,你需要在你的 Message 类中使用 has_one :user

class Message

  has_one :sender, :class_name => 'User', :foreign_key => 'sender_id'

end

之后你可以得到你的消息:

Message.senders 拥有您的所有发件人。

【讨论】:

  • 感谢 shingara,是的,我希望将 User 和 Message 存储在单独的集合中,但我希望在 Message 模型中拥有 User 的副本作为发件人,而不是参考。这是否意味着我应该只是field :sender, :type =&gt; User
  • 你需要在你的用户类上添加一个embedded_in :message
  • 那么用户将被存储在Message集合中,无法直接查询,对吗?
  • 你能补充一下如何保存你的消息/用户吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 2021-07-21
  • 1970-01-01
  • 2015-04-23
  • 1970-01-01
  • 2015-05-13
  • 2011-10-03
相关资源
最近更新 更多