Viewed   135 times

MongoDB updating fields in nested array

How can I set "play" to "play photo" in the photos array?

I only know its _id.

"_id": ObjectId("4f41a5c7c32810e404000000"),
"albums": [
{
    "_id": ObjectId("4f545d1bc328103812000000"),
    "name": "album1" ,
    "photos":[{
        "_id": ObjectId("4f545d1bc328103812d00000"),
        "name":"travel photo"
    },{
        "_id": ObjectId("4f545d1bc328103812c00000"),
        "name":"play"
    }]
},
{
    "_id": ObjectId("4f545f56c328103c12000000"),
    "name": "album2" 
},
{
    "_id": ObjectId("4f545f68c328103012000000"),
    "name": "album3" 
},
{
    "_id": ObjectId("4f546642c328103c12000001"),
    "name": "album4" 
}]

 Answers

4

You can't. The positional operator is only available for the first array in your document hierarchy. As such you cannot manipulate individual elements of deeper nester arrays.

It's a known issue and is scheduled for development here : https://jira.mongodb.org/browse/SERVER-831

Until that time you'll have to normalize your schema a bit I'm afraid.

Wednesday, November 30, 2022
2

I've found a much better solution MongoDB Command

Here is it

<?php
    // Last Online Time
    $Time = time() - 86400;

    // Connection
    $Manager = new MongoDBDriverManager("mongodb://" . DB_USERNAME . ":" . DB_PASSWORD . "@" . DB_HOST . ":" . DB_PORT . "/" . DB_NAME);

    // Command
    $Command = new MongoDBDriverCommand(["count" => "account", "query" => ['LastOnline' => ['$gt' => (int) $Time]]]);

    // Result
    $Result = $Manager->executeCommand(DB_NAME, $Command);

    //print($Result->toArray());Array ( [0] => stdClass Object ( [n] => 228598 [ok] => 1 ) //so n is our totalcount
    // Get Total Online In 1 Hour Ago
    echo count($Result->toArray()[0]->n);
?>
Sunday, October 2, 2022
 
3

If you are using latest MongoDB extension of PHP, MongoDBDriverManager is the main entry point to the extension.

Here is the sample code to retrieve data using latest extension.

Let's say you have testColl collection in testDb. The you can retrieve data using MongoDBDriverQuery class of the extension.

// Manager Class
$manager = new MongoDBDriverManager("mongodb://localhost:27017");

// Query Class
$query = new MongoDBDriverQuery(array('age' => 30));

// Output of the executeQuery will be object of MongoDBDriverCursor class
$cursor = $manager->executeQuery('testDb.testColl', $query);

// Convert cursor to Array and print result
print_r($cursor->toArray());

Output:

Array
(
    [0] => stdClass Object
        (
            [_id] => MongoDBBSONObjectID Object
                (
                    [oid] => 5848f1394cea9483b430d5d2
                )

            [name] => XXXX
            [age] => 30
        )

)
Friday, October 14, 2022
 
ms83
 
3

Ok, the trick was the aggregation framework, specifically unwind.

> db.mytest.aggregate({$unwind: '$top'},
                      {$unwind: '$top.nest'},
                      {$match: {'top.nest.p': 6}}
  )

Though in the case that I had multiple sub matches in a single object, this would return multiple results instead of in their original grouped form. I suppose I can put a $group into the pipeline, though.

Though the related links I found suggested schema redesign as the only complete fix right now, so this is definitely better than nothing.

Saturday, September 3, 2022
 
2

You can do it as follows :

db.collection.update(
  {
    "ID.schoolID": "1234",
    "institution.tests": { $elemMatch: { test: "ACT Composite", mean: null } },
  },
  { $set: { "institution.tests.$.mean": "trial" } }
);
Tuesday, November 29, 2022
 
wavened
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :