如何通过在嵌入式文档数组中查找匹配项来查找文档?

时间:2013-03-19 21:59:36

标签: mongodb mongoid

这看起来很简单,但显然我错过了一些东西。我有一个WebSite模型:

class WebSite
  include Mongoid::Document
  has_many :domains, inverse_of: :web_site
  field :name, type: String
end

WebSite模型具有嵌入式域名阵列:

class Domain
  include Mongoid::Document
  belongs_to :web_site, inverse_of: :domains
  field :name, type: String
end

我要做的就是找到一个域名为“test.com”的网站。我尝试过的任何东西似乎都无法使用Mongoid或MongoDB控制台。例如,如果我有一个带有一个域的WebSite,名称为“test.com”:

2.0.0p0 :001 > WebSite.count
 => 1 
2.0.0p0 :002 > WebSite.first.domains
 => [#<Domain _id: 5148d9b76a3b8b1fe6000003, web_site_id: "5148d9a96a3b8b1fe6000002", name: "test.com">]

...那么这不应该起作用吗?

2.0.0p0 :003 > WebSite.elem_match(domains: { name: "test.com" }).count
 => 0 
2.0.0p0 :004 > WebSite.elem_match('domains' => { 'name' => "test.com" }).count
 => 0 

我得到零。我应该买一个。

我也从O'Reilly的书中得到了这样的印象:

2.0.0p0 :005 > WebSite.where('domains.name' => "test.com").count
 => 0

...与any_in:

相同
.0.0p0 :006 > WebSite.any_in('domains' => { 'name' => "test.com" }).count
=> 0 

我也尝试过来自MongoDB控制台的相同查询,结果相同:

> db.web_sites.find({"domains" : {"$elemMatch" : {"name" : "test.com"}}}).size();
0
> db.web_sites.find({"domains.name" : "test.com"}).size();                       
0
> db.web_sites.find({"domains" : {$in : {"name" : "test.com"}}}).size();
0

我一定错过了什么?

更新

以下是有关该架构的更多信息,来自MongoDB控制台:

> db.web_sites.find().pretty()
{ "_id" : ObjectId("5148d9a96a3b8b1fe6000002"), "name" : "test" }

1 个答案:

答案 0 :(得分:1)

感谢uldall对调试的帮助(那种很棒的漂亮()技术)我意识到我的问题是我有两个独立的集合,而不是嵌入在我的WebSite集合中的Domain集合。这就是我的模型应该如何设置,“embedded_in”和“embeds_many”:

class WebSite
  include Mongoid::Document
  embeds_many :domains, inverse_of: :web_site
  field :name, type: String
end

class Domain
  include Mongoid::Document
  embedded_in :web_site, inverse_of: :domains
  field :name, type: String
end

现在,MongoDB控制台中的文档如下所示:

> db.web_sites.find().pretty()     
{
  "_id" : ObjectId("5148e63f6a3b8b8ffa000001"),
  "domains" : [
    {
      "_id" : ObjectId("5148e6706a3b8b8ffa000002"),
      "name" : "test.com"
    }
  ],
  "name" : "test"
}

使用该架构,这可行:

2.0.0p0 :008 > WebSite.where('domains.name' => 'test.com').count
=> 1

[CHEER]