3

I have a collection in MongoDB called job

    Job{
           _id : ‘12344’,
           cust_id: 'cust1',
           title: 'Create Website',
           description: 'We require it in 2 weeks only',
           location: 'japan',
           images:{
                      'image1',
                      'image2',
                      'image3' 
                  },
            video:{
                      'video1',
                      'video2'
                  },
           budget:'15000',
           duration:'2 weeks',
           Proposals:[{
                           "sender_id" => "5",
                           "description" =>"I can do your task before 2 week", 
                           "date" => "2013-08-05"
                      },
                      {
                            "sender_id" => "6",
                            "description" =>"I can do your task in 2 week, with best quality", 
                            "date" => "2013-08-05"

                      }
                     ]
       }

I want to add messages in proposal attributes whose sender_id=5 like below;

Job{
               _id : ‘12344’,
               cust_id: 'cust1',
               title: 'Create Website',
               description: 'We require it in 2 weeks only',
               location: 'japan',
               images:{
                          'image1',
                          'image2',
                          'image3' 
                      },
                video:{
                          'video1',
                          'video2'
                      },
               budget:'15000',
               duration:'2 weeks',
               Proposals:[{
                               "sender_id" => "5",
                               "description" =>"I can do your task before 2 week", 
                            "date" => "2013-08-05"
                               “messages”:[{
                                         "message_sender" :"Can we meet", 
                                         "date" : "2013-08-06"  
                                       }
                                      ]
                          },
                          {
                                "sender_id" => "6",
                                "description" =>"I can do your task in 2 week, with best quality", 
                            "date" => "2013-08-05"

                          }
                         ]
           }

My document is,

$document = array( 
                    "message_sender" =>"Can we meet", 
                 "date" => "2013-08-06"
         );

I am really having a hard time doing a this thing. which is add a messages to the proposal array. Any help out there with php code?

2 Answers 2

2

This is perfect answer work for me,

db.jobs.update({"_id" : "12344","Proposals.sender_id":"5"},{$push:{"Proposals.$.messages" : { "message" : "Can we meet" , "date":"2013-08-06"}}})
Sign up to request clarification or add additional context in comments.

Comments

0

Often when you run into complications like this, it means you need to split up your subdocuments out into real top-level documents - possibly into a different collection. In this case you will definitely need to push out Proposals into their own collection, and you will need to change your _id and add a job_id to refer back to the real job:

{
    "_id" => …,
    "job_id" => 12344,
    "sender_id" => "5",
    "description" =>"I can do your task before 2 week", 
    "date" => "2013-08-05"
},

{
    "_id" => …,
    "job_id" => 12344,
    "sender_id" => "6",
    "description" =>"I can do your task in 2 week, with best quality", 
    "date" => "2013-08-05"
}

You can then push your new message into the array with:

$document = array( 
    "message_sender" =>"Can we meet", 
    "date" => "2013-08-06"
);

$collection->update(
    array( 'job_id' => 12344, 'sender_id' => "5" ),
    array( 'messages' => array( '$push' => $document ) )
);

Make sure you create an index on job_id, sender_id as well:

$collection->ensureIndex( array( 'job_id' => 1, "sender_id" => 1 ) );

4 Comments

Hi Derick thank you for your valuable suggections.But we just want to know is it possible to implement our structure? If possible then can you please post the query for the same.
No. I don't think you can. You should really consider changing your structure.
Instead of keeping messages an array if I keep message as a string. If I got 100 messages and I am trying to append those messages. Now if I want to fetch particular message, can its possible?
@user2663230: The problem has nothing to do with the messages field being an array. Rather, there is no way to access an element in the top-level Proposals array by some criteria of its object elements. If you knew sender_id: 5 was the first element, you could use $push with Proposals.0.messages, but that isn't reliable. The alternative of making Proposals and object (instead of an array) where the sender ID is used as a key also has trade-offs, most notably that you lose multi-key indexing and the ability to treat Proposals as an array, which it logically is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.