2014-09-18 1 views
1

나는 하나 이상의 객체를 가지고 있습니다. 임베드 된 객체의 파일을 업데이트해야합니다. 여기 내 물건들.mongoid는 여러 객체에 모든 임베드 된 객체를 업데이트합니다.

{ 
    "_id" : ObjectId("50dc134bb4a6de8e6b000001"), 
    "emails" : [ 
     { 
      "_id" : ObjectId("50dc134bb4a6de8e6b000004"), 
      "_type" : "Email", 
      "name" : "personal", 
      "email" : "", 
      "current" : false 
     }, 
     { 
      "_id" : ObjectId("51a855763183a6301e009461"), 
      "_type" : "Email", 
      "name" : "work", 
      "email" : "[email protected]", 
      "current" : true 
     }, 
    ], 
} 
{ 
    "_id" : ObjectId("50dc134bb4a6de8e6b000002"), 
    "emails" : [ 
     { 
      "_id" : ObjectId("50dc134bb4a6de8e6b000067"), 
      "_type" : "Email", 
      "name" : "personal", 
      "email" : "", 
      "current" : false 
     }, 
     { 
      "_id" : ObjectId("51a855763183a6301e004795"), 
      "_type" : "Email", 
      "name" : "work", 
      "email" : "[email protected]", 
      "current" : true 
     }, 
    ], 
} 

컬렉션은 Contact입니다. 여기에 을 설정해야합니다. namepersonal입니다. 나는 루프 기능을 시도했다. 그것은 잘 작동합니다.

하여 MongoDB에서
contacts = Contact.where(:emails.elem_match => {"name" => "personal"}) 
    contacts.each do |contact| 
    contact.email.where("name" => "personal").update_all(:current => true) 
end 

우리는 그래서 내가 알고 싶습니다

db.contacts.update({"emails": {$elemMatch : {"name" : "personal"}},{ $set: {"emails.$.current":true}}) 

처럼 여러 개체를 업데이트 쿼리의 한 줄을 쓸 수있는 여러 업데이트 할 mongoid 쿼리의 한 줄을 쓸 가능성이 있나요 몽고이드에있는 물건들.

답변

1

Mongoid를 사용하는 해당 한 줄 루비 문은 다음과 같습니다

Contact.where(:emails.elem_match => {"name" => "personal"}).update_all("$set" => {"emails.$.current" => true}) 

여기 그것이 작동하는 증거입니다.

응용 프로그램/모델/contact.rb

class Contact 
    include Mongoid::Document 
    embeds_many :emails 
end 

응용 프로그램/모델/email.rb

class Email 
    include Mongoid::Document 
    field :name, type: String 
    field :email, type: String 
    field :current, type: Boolean 
    embedded_in :contact 
end 

테스트/단위/contact_test.rb

require 'test_helper' 
require 'pp' 

class ContactTest < ActiveSupport::TestCase 
    def setup 
    Contact.delete_all 
    end 
    test '0. mongoid version' do 
    puts "\nMongoid::VERSION:#{Mongoid::VERSION}\nMoped::VERSION:#{Moped::VERSION}\nRails.version:#{Rails.version}" 
    end 
    test 'update all embedded objects' do 
    docs = [ 
     { 
      "_id" => Moped::BSON::ObjectId("50dc134bb4a6de8e6b000001"), 
      "emails" => [ 
       { 
        "_id" => Moped::BSON::ObjectId("50dc134bb4a6de8e6b000004"), 
        "_type" => "Email", 
        "name" => "personal", 
        "email" => "", 
        "current" => false 
       }, 
       { 
        "_id" => Moped::BSON::ObjectId("51a855763183a6301e009461"), 
        "_type" => "Email", 
        "name" => "work", 
        "email" => "[email protected]", 
        "current" => true 
       }, 
      ], 
     }, 
     { 
      "_id" => Moped::BSON::ObjectId("50dc134bb4a6de8e6b000002"), 
      "emails" => [ 
       { 
        "_id" => Moped::BSON::ObjectId("50dc134bb4a6de8e6b000067"), 
        "_type" => "Email", 
        "name" => "personal", 
        "email" => "", 
        "current" => false 
       }, 
       { 
        "_id" => Moped::BSON::ObjectId("51a855763183a6301e004795"), 
        "_type" => "Email", 
        "name" => "work", 
        "email" => "[email protected]", 
        "current" => true 
       }, 
      ], 
     } 
    ] 
    Contact.collection.insert(docs) 
    # contacts = Contact.where(:emails.elem_match => {"name" => "personal"}) 
    # contacts.each do |contact| 
    # contact.emails.where("name" => "personal").update_all(:current => true) 
    # end 
    #db.contacts.update({"emails": {$elemMatch : {"name" : "personal"}},{ $set: {"emails.$.current":true}}) 
    Contact.where(:emails.elem_match => {"name" => "personal"}).update_all("$set" => {"emails.$.current" => true}) 
    puts 
    contacts = Contact.all.to_a 
    contacts.each do |contact| 
     emails = contact["emails"].select{|email| email["name"] == "personal"} 
     assert_equal(true, emails.first["current"]) 
    end 
    pp contacts.collect{|contact| contact.serializable_hash} 
    end 
end 

레이크 시험

Run options: 

# Running tests: 

[1/2] ContactTest#test_0._mongoid_version 
Mongoid::VERSION:3.1.6 
Moped::VERSION:1.5.2 
Rails.version:3.2.17 
[2/2] ContactTest#test_update_all_embedded_objects 
[{"_id"=>"50dc134bb4a6de8e6b000001", 
    "emails"=> 
    [{"_id"=>"50dc134bb4a6de8e6b000004", 
    "current"=>true, 
    "email"=>"", 
    "name"=>"personal"}, 
    {"_id"=>"51a855763183a6301e009461", 
    "current"=>true, 
    "email"=>"[email protected]", 
    "name"=>"work"}]}, 
{"_id"=>"50dc134bb4a6de8e6b000002", 
    "emails"=> 
    [{"_id"=>"50dc134bb4a6de8e6b000067", 
    "current"=>true, 
    "email"=>"", 
    "name"=>"personal"}, 
    {"_id"=>"51a855763183a6301e004795", 
    "current"=>true, 
    "email"=>"[email protected]", 
    "name"=>"work"}]}] 
Finished tests in 0.083133s, 24.0578 tests/s, 24.0578 assertions/s. 
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips 
+0

고마워, 게리 무라카미, 나는 이미 이것을 시도했다. 그것은 작동하지 않았다. – Selvamani

+0

전액 증거로 답변을 업데이트했습니다. mongo 쉘 라인과 동등하게 작동한다는 것을 스스로 확신 할 수 있습니다. –

+0

@gary는 많은 품질의 답변을 제공해 주셔서 감사합니다. 이것에 대한 제안이 있습니까 : http://stackoverflow.com/questions/29719471/mongodb-mongoid-rails-unable-to-increment-counters-in-a-hash-in-embedded-documen – brg