0

我有一个带有多个嵌入式模型的模型。我需要查询一条记录以查看它是否存在。问题是我必须包含对多个嵌入文档的引用,我的查询必须包含以下参数:

{
 "first_name"=>"Steve",
 "last_name"=>"Grove",
 "email_addresses"=>[
     {"type"=>"other", "value"=>"steve@stevegrove.com", "primary"=>"true"}
 ],
 "phone_numbers"=>[
     {"type"=>"work_fax", "value"=>"(720) 555-0631"},
     {"type"=>"home", "value"=>"(303) 555-1978"}
 ],
 "addresses"=>[
     {"type"=>"work", "street_address"=>"6390 N Main Street", "city"=>"Elbert", "state"=>"CO"}
 ],
}

即使缺少某些字段(例如 _id 和关联),我如何查询所有嵌入式文档?

4

3 回答 3

1

有几件事要考虑。

  1. 您确定查询必须包含所有这些参数吗?是否存在唯一标识记录的信息子集?说 ( first_name,last_name和 an email_addresses.value)。如果您可以用更少的工作完成同样的事情,那么查询所有条件将是愚蠢的。

  2. 在 Mongoid 中,where条件允许您直接使用 javascript,因此如果您知道如何编写 javascript 条件,您可以将一个 javascript 字符串传递给 where。

  3. 否则你会写一个非常尴尬的 where 条件语句,幸好你可以使用点符号。

就像是:

UserProfile.where(first_name: "Steve", 
                   last_name: "Grove", 
                   :email_addresses.matches => {type: "other", 
                                                value: "steve@stevegrove.com", 
                                                primary: "true"}, 
                    ..., ...)
于 2012-05-02T15:46:27.530 回答
0

响应嵌入式js的请求:

query = %{
  function () {
    var email_match = false;
    for(var i = 0; i < this.email_addresses.length && !email_match; i++){
      email_match = this.email_addresses[i].value === "steve@stevegrove.com";
    }
    return this.first_name === "Steve" &&
      this.last_name === "Grove" &&
      email_match;
  }
}
UserProfile.where(query).first

它不漂亮,但它有效

于 2013-02-01T23:42:19.113 回答
0

使用 Mongoid 3,您可以使用elem_match http://mongoid.org/en/origin/docs/selection.html#symbol

UserProfile.where(:email_addresses.elem_match => {value: 'steve@stevegrove.com', primary: true})

这假设

class UserProfile
  include Mongoid::Document
  embeds_many :email_addresses
end

现在,如果您需要包含这些字段中的每一个,我建议您使用UserProfile.collection.aggregate(query). 在这种情况下,您可以构建一个包含所有字段的巨大哈希。

query = { '$match' => {
  '$or' => [
    {:email_addresses.elem_match => {value: 'steve@stevegrove.com', primary: true}}
  ]
} }

它开始变得有点疯狂,但希望这能让您对您的选择有所了解。https://coderwall.com/p/dtvvha再举一个例子。

于 2014-04-16T17:13:48.140 回答