Asked  7 Months ago    Answers:  5   Viewed   37 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

29

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, March 31, 2021
 
jcubic
answered 7 Months ago
35

Your driver will use a MongoDate time (this may map to a more native representation in PHP).
You can then query using something like the following mongo statement:

db.myCollection.find({updated : { $lte : new ISODate("2012-06-09T16:22:50Z") } })

A rough translation for PHP would be:

$search = array(
  'updated' => array(
    '$lte' => new MongoDate($tenMinutesAgo))
);
$collection->find($search)

Or (Caveat: not tested):

$tenMinutesAgo = new DateTime();
$tenMinutesAgo->modify('-10 minutes');

$search = array('updated' => array('$lte' => $tenMinutesAgo));
$collection->find($search)
Wednesday, March 31, 2021
 
SkyNet
answered 7 Months ago
90

findOne() does not return a cursor like find() does - please check the documentation here:

http://www.php.net//manual/en/mongocollection.findone.php

In addition you appear to have a syntax error in your code, you are missing a right parentheses in the first line. Also, using variables named "$cursor" when it's not returning a cursor tends to be a bad idea as it causes confusion for those viewing the code.

Finally, you are using different approaches between your two code samples - different variable names, different strings passed to MongoClient(), one uses a call to MongoCollection() and one does not, etc - very easy for problems to crop up in those differences.

Taking all that into account, I'd propose the following:

# Add right ) at end of following statement
$email = array('email' => $_POST['email']);
$conn = new MongoClient("mongodb://localhost:27017/");
$db = $conn->database;
$collection = new MongoCollection($db, 'users');
$findoneResult = $collection->findOne($email); 
print_r ($findOneResult);
Saturday, May 29, 2021
 
Trott
answered 5 Months ago
18

Probably something like this where ID is your ObjectId. The first {} are necessary to identify your document. It is not required to use an ObjectId as long as you have another unique identifier in your collection.

db.collection.update(
    { "_id": ID, "playlists._id": "58"},
    { "$push": 
        {"playlists.$.musics": 
            {
                "name": "test name",
                "duration": "4.00"
            }
        }
    }
)
Tuesday, June 1, 2021
 
fhonics
answered 5 Months ago
75

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

This query work for me:

db.getCollection('testeur').find({ "attributes": {
        $exists: true, 
        $ne: [],
        $elemMatch: { "value": {$exists: false } } 
    }
})
Saturday, October 9, 2021
 
Mike Caron
answered 1 Week ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :