Pergunta

Hi i'm really mongodb newbie.

I have a document like this:

{
    "_id": ObjectId("53182e32e4b0feedb1dea751"),
    "solutions": [
        [
            {
                "solution": "Double Room Economy (Without Breakfast)",
                "board": "Room Only",
                "id": "HK-15501871",
                "price": 5000,
                "available": "1",
                "CXL": "[]",
                "unique": 0
            },
            {
                "solution": "Double Room Economy (With Breakfast)",
                "board": "Room Only",
                "id": "HK-15501871",
                "price": 4600,
                "available": "1",
                "CXL": "[]",
                "unique": 1
            },
            {
                "solution": "Double Room Economy (Room Only)",
                "board": "Room Only",
                "id": "HK-15501871",
                "price": 5500,
                "available": "1",
                "CXL": "[]",
                "unique": 2
            }
        ]
    ]
}

And i need to update the field CXL inside the second array of solutions. so solutions.1.CXL

This is how i take document:

$collection = $this->getCollection();
$query      = array("_id"=>new MongoId($id));       
$document   = $collection->findOne($query);

now i need to update that field without touch the other.

How can i do?

Thanks!

SOLVED THANKS TO @Sammaye

i solved in this way:

$collection->update(
    array('_id' => new MongoId('..')),
    array('$set' => array('solutions.0.1.CXL' => 'something'))
);
Foi útil?

Solução

Edit

To actually update by the first index then you can do:

$db->collection->update(
    ['_id' => new \MongoId($id)],
    ['$set' => ['solutions.0.1.CLX' => 'whatever']]
);

I misread the question in posting the information below:

So what you wanna update all CXL fields in the document (since you are only searching by top level document _id)?

That isn't possible without manually pulling this document out and iterating the subdocuments in the solutions field and then resaving it.

This is becausde there is currently no way of saying, "Update all that match"

This, however, is most likely the JIRA you would want to look for: https://jira.mongodb.org/browse/SERVER-1243

Outras dicas

As long as you know you are going to update the second element then use the index of the array to do so. But that problem next. First you need the $set operator in order not to blow away your document and just set the field value:

db.collection.update(
    { _id: ObjectId("53182e32e4b0feedb1dea751") },
    { $set: { "solutions.0.1.CXL": [ 1, 2, 3 ] } }
)

If you just want to add to the array rather than replace the whole thing, then just use $push instead:

db.collection.update(
    { _id: ObjectId("53182e32e4b0feedb1dea751") },
    { $push: { "solutions.0.1.CXL": 4 } }
)

If you are paying attention to the notation, then you will notice that the array index values are present in the field to be updated. There is a very good reason for this, which can be read on the documentation for the positional $ operator.

The issue is that you have a nested array, which as the documentation refers to, causes a problem if you try to match items within that nested array. That problem is, if you try to use the "positional" operator to find the matched index of something you look for in a query, then it will contain the value of the first array index match that it finds.

In this case that would be your "top level" array and the "found" index is 0 and not 1 as you may expect.

Please be aware of this issue if you intend to use nested arrays.

You can update like this:

update({ 
       _id: ObjectId("53182e32e4b0feedb1dea751"), 
       solutions.id: HK-15501871,
       solutions.CLX: "Whatever!",")
   },{
       $set: {"comments.$.type": abc}
   }, false, true
);

You may want to go through this once

http://docs.mongodb.org/manual/reference/method/db.collection.update/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top