I moved from mongo to mongodb extension when I upgraded to PHP7. The only thing I cannot figure out is to update a doc by id. Mongo used to have the MongoId Class to parse the id from string but I can't find any equivalent for Mongodb.
This is where I'm at and which doesn't work
$collection->updateOne(['_id' => '567eba6ea0b67b21dc004687'], ['$set' => ['some_property' => 'some_value']]);
The _id should be a instance of BSON:
$collection->updateOne(['_id' => new \MongoDB\BSON\ObjectID('567eba6ea0b67b21dc004687')], ['$set' => ['some_property' => 'some_value']]);
Related
I have two databases, MYSQL and MongoDB, as MongoDB works with Documents I need a way to fetch data from MongoDB using in-URL parameters. Sensio/Framework-Extra-Bundle had this feature, but its going to be abandoned and I decided to switch on Symfony Attributes instead.
With Sensio/Framework-Extra-Bundle #[ParamConverter] that would look something like this:
#[Route('/{slug}', methods: ['GET'])]
#[ParamConverter('slug', options: ['finder' => 'CustomFinder', 'attributes' => ['id']])]
Since they switched over to Symfony Attributes and now they are using #[MapEntity] I'm not sure this is possible anymore.
I have tried to do similar with #[MapEntity] like this:
#[MapEntity(mapping: ['finder' => 'CustomFinder', 'slug' => 'id'])] MyDocument $document
But I'm getting this error:
Uncaught Error: App\Controller\MyController::get(): Argument #1 ($document) must be of type App\Document\MyDocument, string given, called in /app/vendor/symfony/http-kernel/HttpKernel.php on line 163
Try this:
#[MapEntity(mapping: ['finder' => 'CustomFinder', 'id' => 'slug'])] MyDocument $document
when using the update statement via PHP means am getting the error.
Call to undefined method MongoDB::update()
I'm using the mongo-php-driver driver for connecting the MongoDB and PHP
My Code
$result = $this->mongo_db->update('table_name',array('user_type'=>"D"),array('$set'=>array('account_balance'=>0)),array('upsert'=>true));
My MongoDB reference link is https://docs.mongodb.com/manual/reference/method/db.collection.update/
Hi am using updateMany instead of update. Its working fine for me.
$result = $this->mongo_db->updateMany('table_name',array('user_type'=>"D"),array('$set'=>array('account_balance'=>0)),array('upsert'=>true));
From the documentation
Use the MongoDB\Collection::updateOne() method to update a single document matching a filter. MongoDB\Collection::updateOne() returns a MongoDB\UpdateResult object, which you can use to access statistics about the update operation.
<?php
$collection = (new MongoDB\Client)->test->users;
$collection->drop();
$collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
$collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
$updateResult = $collection->updateOne(
['state' => 'ny'],
['$set' => ['country' => 'us']]
);
printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
For Extra Read:
The MongoDB PHP Library and underlying mongodb extension have notable API differences from the legacy mongo extension. Please read the upgrade guide for more details.
You should check if the mongo db extension is installed and available. Install it with pecl:
https://stackoverflow.com/a/74844843/2862728
I am using the Lithium framework version 1.1.1 in PHP 5.6 with MongoDB. I have updated MongoDB from 3.4 to 3.6 and this ended up requiring the PHP ini variable mongo.long_as_object be set to true for the aggregateCursor() methods to work properly in the legacy MongoDB driver for PHP. This version of Lithium does not yet support the newer MongoDB PHP module. This causes a problem with the way NumberLong values are handled in Lithium since they are converted to a MongoInt64 in PHP.
For example: When calling $results->data() on a DocumentSet, a BSON result such as { viewers: NumberLong(12345) } will decode to [ 'viewers' => [ 'value' => '12345' ] ]. Instead I need the PHP array to be [ 'viewers' => 12345 ].
If I add an appropriate handler directly in the lithium\data\entity\Document::_init method then everything works as I expect. For example:
$this->_handlers += [
'MongoId' => function($value) { return (string) $value; },
'MongoDate' => function($value) { return $value->sec; },
'MongoInt64' => function($value) { return (int) $value->value; }
];
However, directly editing the Lithium library is likely not the best approach especially when upgrading the library to newer version as they are released. Is there a proper way to add this handler elsewhere? Such as in the Connections::add(...) method in the connections.php bootstrap file?
Unfortunately, handlers aren't directly configurable, however, they're not too hard to override. You can pass a classes key to Connections:add(), which allows you to extend one of the two classes where handlers are specified, i.e.:
Connections::add([
/* ... */,
'classes' => [
'entity' => 'my\data\Document'
// -- or --
'schema' => 'my\data\Schema'
]
]);
From there, you can implement your custom class that extends the appropriate core class, adding extra handlers as appropriate. Also, a PR to add MongoInt64 support to Li3 core would be gratefully accepted. :-)
I'm fairly new to Mongo and I have what I thought was a simple question. How do I do MapReduce with PHP and the non legacy MongoDB driver http://php.net/manual/en/set.mongodb.php or the higher level package mongodb/mongodb found at https://packagist.org/packages/mongodb/mongodb?
Every example I've seen seems to use the legacy driver (http://php.net/manual/en/book.mongo.php). They all use the MongoCode object, which doesn't exist in mongodb.php. It exists in mongo.php (the legacy driver). When I try and use it, it will say that "Class 'MongoCode' not found".
My code looks something like:
$function = "function() { emit(this); }";
$map = new \MongoCode($function);
$command = $db->command([
"mapreduce" => "db.archiveData",
"map" => $map,
"query" => $query,
"out" => "data"
]);
To make things more confusing, when I look at the source at https://github.com/mongodb/mongo-php-library, there is a unit test for MapReduce (https://github.com/mongodb/mongo-php-library/blob/4dc36f6231df133a57ff0dc5a0123945133d25ba/tests/Operation/MapReduceFunctionalTest.php). But it uses the MongoDB\Operation\MapReduce, which doesn't seem to exist in the 1.1 version of mongodb/mongodb.
I thought maybe I would call it on the server using JavaScript. But when I look at http://php.net/manual/en/mongodb.execute.php, it says it "is deprecated in MongoDB 3.0+". So that doesn't feel like something I should use.
So is it that:
MapReduce is not supported with mongodb/mongodb. Or maybe it is not supported yet, but will be?
I have to use the legacy driver for MapReduce?
I have to figure out a way to call db.collection.mapReduce via JavaScript on the server?
I have to use the Aggregation Pipeline (https://docs.mongodb.com/manual/aggregation/) to do map reduce type of actions? But that feels much more limited.
What am I missing?
So I now have clarity on where things are at.
MapReduce will be officially supported in 1.2.0 of PHPLib (https://jira.mongodb.org/browse/PHPLIB-53)
Until then, there is a completely usable workaround by using the command object as per https://docs.mongodb.com/php-library/current/upgrade/#mapreduce-command-helper
Example is here as well:
$database = (new MongoDB\Client)->selectDatabase('db_name');
$cursor = $database->command([
'mapReduce' => 'collection_name',
'map' => new MongoDB\BSON\Javascript('...'),
'reduce' => new MongoDB\BSON\Javascript('...'),
'out' => 'output_collection_name',
]);
$resultDocument = $cursor->toArray()[0];
You can also use MapReduce via Doctrine (http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/map-reduce.html), but that is using legacy and a shim. So probably not a good choice for a new project.
We're using APCu as a data cache for PHP on a number of different installations - workstations, development and production servers. Unfortunately, the APCu API appears to be a moving target, and there is little to no official documentation (that I could find). At the moment, we're getting quite different return values for apcu_cache_info()...
With APCu 4.0.1, an entry looks like this:
[
'key' => 'the_entry_key',
'atime' => 1450646021,
'ctime' => 1450646021,
'mtime' => 1450650861,
'dtime' => 0,
// ...
]
With APCu 4.0.7, it looks like this:
[
'info' => 'the_entry_key',
'access_time' => 1450650861,
'creation_time' => 1450646021,
'modification_time' => 1450646021,
'deletion_time' => 0,
// ...
]
According to the source on GitHub, it now looks like this:
[
'info' => 'the_entry_key',
'access_time' => 1450650861,
'creation_time' => 1450646021,
'mtime' => 1450646021,
'deletion_time' => 0,
// ...
]
We've seen other sudden API changes in the past, like when apcu_sma_info() and apcu_cache_info() had to be called with the string "user" as the first parameter - until they didn't. I understand that these changes are related in some way with keeping or dropping compatibility with the old APC extension, but it's getting a little hard to guess how to interact with APCu.
Are these changes documented somewhere, with a version number we can check against? Are there going to be any more changes to this in the near future? How can I get notified about them, other than seeing my application break?
The documentation on php.net has nothing to say about this, and neither does the project's CHANGELOG file. The PHP change log doesn't mention this as a backwards incompatible change either (probably because APCu isn't bundled with PHP by default).