Comments (7)
Hello!
I've found a way to do it, but I'm not sure this is the correct one:
$instance->setName('bar');
$collection->updateOne(['_id' => $result->getInsertedId()], [
'$set' => $instance->bsonSerialize()
]);
/**
* > db.coll.findOne()
* {
* "_id" : ObjectId("56a366dc046d5f0055094a91"),
* "__pclass" : BinData(128,"QQ=="),
* "name" : "bar"
* }
*/
What do you think?
from mongo-php-library.
No.
After second tought, this is definitly not a good idea. bsonSerialize()
is used internally by the MongoDB driver. Anyway it doesn't work with embedded document.
from mongo-php-library.
I believe the problem is due to your class not handling the _id
field.
When inserting the instance, bsonSerialize()
returns a document containing only a name
field, which leaves the driver to generate an ObjectId on its own (the same that you later retrieve from the write result). When replacing the document, bsonSerialize()
is again invoked and returns another document containing only name
but with a different value. In my local test, that replacement does achieve the desired goal of changing the name
field of the inserted document. I verified this using the shell to dump the document after the insertOne()
and replaceOne()
calls and there is but one document in the collection:
> db.coll.find()
{ "_id" : ObjectId("56a6a61c6118fd39a911c6e1"), "name" : "bar" }
I would suggest the following to properly handle the _id
property on your class:
- Add an
$_id
property on the class (or whatever you'd like the name it) - Ensure the property is included in
bsonSerialize()
if set. Unless you plan to initialize$_id
to a new ObjectId (or some other value) during construction, I'd suggest you not include it inbsonSerialize()
if it'snull
, as that will happy create a document in MongoDB with anull
ID value (and naturally start throwing duplicate key exceptions after the first insertion). - Ensure the property is picked up in
bsonUnserialize()
.
For example:
class A implements MongoDB\BSON\Persistable
{
private $_id;
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function setName($name)
{
$this->name = $name;
}
public function bsonSerialize()
{
$data = [
'name' => $this->name,
];
if ($this->_id !== null) {
$data['_id'] = $this->_id;
}
return $data;
}
public function bsonUnserialize(array $data)
{
$this->name = $data['name'];
$this->_id = $data['_id'];
}
}
That said, I think it would be easiest to assign a new MongoDB\BSON\ObjectID
to $this->_id
in your constructor and simplify bsonSerialize()
. I expect this may end up being a common mistake for new users, so I will get this added to our documentation examples soon (both on PHP.net and in the upcoming library documentation for using Persistable and the other two interfaces).
That said, there is a driver problem here (below the library). The __pclass
property is disappearing after the replacement is executed. Curiously, it is present when we debug the replacement document through the BSON serialization functions:
echo MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($instance));
// outputs: { "__pclass" : { "$type" : "80", "$binary" : "QQ==" }, "name" : "bar" }
Looking into the extension code, I believe we're missing PHONGO_BSON_ADD_ODS|PHONGO_BSON_ADD_CHILD_ODS
flags when encoding the replacement arguments in BulkWrite.c. Those are flags we use when inserting documents, and I believe missing them for replacements was an oversight. I'll look into that and cross-reference this with a JIRA ticket on the extension soon.
Thanks for the report!
from mongo-php-library.
Cross-referencing:
- https://jira.mongodb.org/browse/PHPC-549 for documentation improvements
- https://jira.mongodb.org/browse/PHPC-550 for replacement doc encoding bug
from mongo-php-library.
FYI, while waiting for the fix, one must specificaly serialize the __pclass
property to prevent metadata to be le lost on document update:
public function bsonSerialize()
{
return [
'_id' => $this->id,
'__pclass' => new BSON\Binary(get_class($this), BSON\Binary::TYPE_USER_DEFINED),
//... whatever other fields you want to persist
];
}
from mongo-php-library.
FYI: PHPC-550 has been merged and is slated for a 1.1.3 release this week.
from mongo-php-library.
1.1.3 has been released, so I think this can be closed. Feel free to follow up if the issue persists.
from mongo-php-library.
Related Issues (20)
- PHP+MongoDB: "Return value must be of type MongoDB\Driver\Server, null returned" HOT 3
- Can we drop `jean85/pretty-package-versions:1.2`? HOT 4
- Decision about `mongo-orchestration` folder and `Makefile` HOT 3
- [Documentation] Syntax highlighting in the method reference is not ideal HOT 1
- A never-ending query after upgrade to MongoDB 6.0.3 HOT 6
- Memory leak on updateOne in the loop HOT 1
- Deprecated: Return type of MongoDB\Model\BSONDocument::bsonSerialize() HOT 2
- The StreamWrapper class is currently unusable without the bucket HOT 4
- Performance issue with PHP 8.2 HOT 2
- Extract mongodb-1.6.2.tgz error HOT 1
- MacOs M1 Cannot connect to Atlas After upgrade driver HOT 7
- This is a test
- get_debug_type() only available for PHP 8.0 and up HOT 2
- How to execute refreshSessions HOT 1
- Can't connect. To mongo db remote in can bost HOT 1
- Non blocking io HOT 1
- $where is not allowed in this context HOT 2
- TLS connection with mongo cluster failed (while single host works) HOT 2
- getting result from mongodb with toArray() HOT 3
- Getting the error in driver version 1.14 HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mongo-php-library.