0

Hi i am new to mongodb and i am using PHP here. I want to update the sub-document with an array like below to existing document.

[weeksAtOne] => Array
    (
        [156] => 1586
    )

when i try to call the below functions

$query = array('decade' => array('$in' => array(1980,1990)));   
$songs->update($query, 
        array('$push'=>array('weeksAtOne'=>array(156 => 500))),
        array('safe'=>true,'timeout'=>5000,'multiple'=>true))

It is not coming as expected instead it will coming differently. Could you please someone guide me which is the right way to update this.

Original Array:

Array
(
[_id] => MongoId Object
    (
        [$id] => 55004cbd30d6d48819000004
    )

[decade] => 1980
[artist] => Olivia Newton-John
[song] => Physical
[weeksAtOne] => Array
    (
        [10] => 10
        [11] => 100
        [22] => 500
    )

 )
Array
(
[_id] => MongoId Object
    (
        [$id] => 55004cbd30d6d48819000005
    )

[decade] => 1990
[artist] => Mariah Carey
[song] => One Sweet Day
[weeksAtOne] => Array
    (
        [10] => 16
        [21] => 100
        [23] => 500
    )

)

Expected Output:

Array
(
[_id] => MongoId Object
    (
        [$id] => 55004cbd30d6d48819000004
    )

[decade] => 1980
[artist] => Olivia Newton-John
[song] => Physical
[weeksAtOne] => Array
    (
        [10] => 10
        [11] => 100
        [22] => 500
        [156] => 1586
    )

 )
Array
(
[_id] => MongoId Object
    (
        [$id] => 55004cbd30d6d48819000005
    )

[decade] => 1990
[artist] => Mariah Carey
[song] => One Sweet Day
[weeksAtOne] => Array
    (
        [10] => 16
        [21] => 100
        [23] => 500
        [156] => 1586
    )

)
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • i'm having a hard time understanding your question...can you try to condense exactly what you're trying to achieve and what's going wrong please – jtmarmon Mar 11 '15 at 18:19
  • @jtmarmom - I want to push an associated array value into the sub-document "weeksAtOne" array. So i tried to update like above, not it is not coming as expected instead it is creating one more array inside weeksAtOne array. – Vinodkumar Saravana Chandrasek Mar 17 '15 at 04:41

1 Answers1

0

Your structure for "weeksAtOne" is not a true array but what is often referred to as an "associated array" or "hash" or "map". PHP blurs the lines on this but most languages have clear distinctions between the two.

In brief your document looks like this in JSON notation:

{
    "weeksAtOne": {
        "10": 16,
        "21": 100,
        "23": 500
    }
}

The $push operator is intended for true arrays, or things that look like this:

{
    "weeksAtOne": [
        { "10": 16 },
        { "21": 100 },
        { "23": 500 }
    ]
}

What you want is the $set operator and use MongoDB's "dot notion" to specify the inner "key" element of that sub-document:

$query = array('decade' => array('$in' => array(1980,1990)));   
$songs->update($query, 
    array('$set'=>array('weeksAtOne.156'=> 1586)),
    array('safe'=>true,'timeout'=>5000,'multiple'=>true))

That will create a new key within the sub-document of each matched document and set the requested value.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317