0

I am new to NoSQL and MongoDB and I am trying to $push an array into another field that is an array.

I am trying to push $dynamicInfo into my user's profile.weightTracker so that I can have a new array into weightTracker the current code push by replace but not push the array as a new array every time I refresh the page / run the scrip but instead re-writes the current.

Could anyone point out what am I doing wrong?

Thanks in advance.

$dynamicInfo['currentWeight'] = '83';

$user = $this->db()->users;

// Deals with the static info that just need an update
if ( empty( $staticInfo ) == false ) {
    $user->update(
        array('_id' => new MongoId( $userId ) ),
        array('$set' => array('profile' => $staticInfo) ),
        array('upsert' => True)
    );
}

// Deals with the dynamic info that needs to be inserted as array
if ( empty( $dynamicInfo ) == false ) {
    //$dynamicInfo['inserted_on'] = new MongoDate();
    $user->update(
        array('_id' => new MongoId( $userId ) ),
        array('$push' => array('profile.weightTracker' => $dynamicInfo ) ),
        array('safe' => True)
    );
}

enter image description here

4

1 回答 1

2

I am going to expect that the code that deals with static information over writes the document each time you run it, and then the code that deals with dynamic information just the first array element again. In other words, I don't think $staticInfo is empty when you expect it to be.

If you do:

$user->update(
    array( '_id' => 42 ),
    array( '$set' => array( 'profile.weightTracker' => array( 'height' => 82 ) ) )
);

and then:

$user->update(
    array( '_id' => 42 ),
    array( '$set' => array( 'profile' => array( 'height' => 176 ) ) )
);

Then the whole array profile will be set to array( 'height' => 176 ). It doesn't matter if you have set 'profile.weightTracker' to some other value before.

You can't set an array (profile) and expect sub keys that you don't specify in the first update (profiler.weightTracker) to survive.

However, what you can do is this — simply build up the $set array and run the update in one go:

$user->update(
    array( '_id' => 42 ),
    array(
        '$push' => array( 'profile.weightTracker' => array( 'currentWeight' => 82 ) ),
        '$set' => array( 'profile.height' => 176 )
    )
);
于 2013-07-30T08:37:32.780 回答