Reputation: 2754
I have a file with following data exported with mongodb mongoexport command:
mongoexport --db mydb --collection Users --out Users.json --jsonArray --journal
Users.json contains:
[
{
"_id" : { "$oid" : "53c3e81ebb593fe827040ef7" },
"email" : "[email protected]",
"password" : "$2y$10$OYN9qOPa8EAU202Nsee7s.jDyT8ntHq2mBkM4wWAMxDYvARRyKmr2"
}
]
I want to import data without mongoimport command, just using php client, so I do
$fixtures = file_get_contents($fixturesPath . '/' . $fixtureFile);
$rows = json_decode($fixtures, true);
foreach ($rows as $row) {
$this->db->Users->insert($row);
}
var_dump of $row just before the insert is correct:
(
[_id] => Array
(
[$oid] => 53c3e81ebb593fe827040ef7
)
[email] => [email protected]
[password] => $2y$10$OYN9qOPa8EAU202Nsee7s.jDyT8ntHq2mBkM4wWAMxDYvARRyKmr2
)
I get the following error:
[MongoWriteConcernException]
localhost:27017: $oid is not valid for storage.
The question is, how can I do to import this data from php ?
Obviously by removing _id line it works, but I think I need this id so I can tests always with the user ids .
Upvotes: 2
Views: 6322
Reputation: 2754
Neil Lunn, and Sammaye, are correct. They pointed me to the solution, and marked Neils as correct.
But also wanted to leave here my own solution as you can also have subdocuments I ended writing this recursive function to replace all $oid
private function replaceMongoIds(&$document, $name = false)
{
foreach (array_keys($document) as $key) {
if ($key == "_id" && isset($document[$key]['$oid'])) {
$document[$key] = new \MongoId($document[$key]['$oid']);
} else if ($name && is_array($document[$key]) && isset($document[$key]['$oid'])) {
$document[$key] = new \MongoId($document[$key]['$oid']);
} else if (is_array($document[$key]) ) {
$this->replaceMongoIds($document[$key], $key);
}
}
}
so now my code looks like
$fixtures = file_get_contents($fixturesPath . '/' . $fixtureFile);
$rows = json_decode($fixtures, true);
foreach ($rows as $row) {
$this->replaceMongoIds($row);
$this->db->Users->insert($row);
}
Upvotes: 3
Reputation: 151122
By default, uses the "extended JSON syntax" standard for MongoDB. This is because JSON is not "typed" where BSON is and certain data is expected to be "typed", in this case the ObjectId
.
So if you are dealing with JSON in the "extended syntax" form then you need to convert it:
foreach ( $rows as $row ) {
foreach ( array_keys($row) as $key) {
if ( $key == "_id" ) {
$row[$key] = new \MongoId( $row[$key]['$oid'] );
}
}
$this->db->Users->insert( $row );
}
Or something similar, as looping here would be more practical if you were "detecting" this and other types. But basically you need to "convert" any of these special types from that extended representation in JSON.
Upvotes: 5