I have used the below code to insert Primary category id reference to Secondary category document using robomongo client
var parentDoc = db.getCollection('category').findOne({"slug":"Primary"});
db.category.insert(
{
"name" : "Secondary",
"slug" : "secondary",
"taxonomy" : true,
"ancestors" : [
{
"_id" : parentDoc._id,
"name" : parentDoc.name
}
]
})
i have tried the below in PHP style
$query = '
{
"slug" : "fashion"
}';
$primaryCategory = Category::findFirst(array(json_decode($query,true))); //phalcon code
$primary = array();
$primary['_id'] = $primaryCategory->_id;
$primary['name'] = $primaryCategory->name;
$document = array(
"name" => "Secondary2",
"slug" => "secondary",
"taxonomy" => true,
"ancestors" => array($primary)
);
$category = $app->mongo->selectCollection('category');//phalcon style of fetching collection handle
$category->insert($document);
});
And tried in Phalcon style
$query = '
{
"slug" : "fashion"
}';
$primaryCategory = Category::findFirst(array(json_decode($query,true)));
$cat = new Category(); // new secondary category
$cat->name = 'Secondary';
$cat->slug = 'secondary';
$cat->taxonomy = true;
$cat->ancestors = array();
$primary = array();
$primary['_id'] = $primaryCategory->_id;
$primary['name'] = $primaryCategory->name;
array_push ( $cat->ancestors, $primary );
$cat->save();
In the above code there are 2 round trips between server and mongo
Is it possible to execute them in 1 roundtrip where I could reference the parentDocId while secondaryDoc insertion
You can leverage your insert operations by using the Bulk API which is available from MongoDB 2.6 or higher. The current PHP driver should support these methods, where in particular you need the MongoWriteBatch class which extends the MongoInsertBatch class for insert operations. In essence, the operation can be implemented as following:
<?php
$mc = new MongoClient("localhost");
$collection = $mc->selectCollection("test", "category");
$batch = new MongoInsertBatch($collection);
$counter = 0;
$query = array("slug" => "Primary");
foreach ($collection->find($query) as $doc ) {
$primary = array();
$primary['_id'] = $doc->_id;
$primary['name'] = $doc->name;
$doc = array(
"name" => "Secondary2",
"slug" => "secondary",
"taxonomy" => true,
"ancestors" => array($primary)
);
$batch->add($doc);
$counter++;
if ( $counter % 1000 === 0 ) {
$ret = $batch->execute(array("w" => 1));
$counter++;
$batch = new MongoInsertBatch($collection);
}
}
if ( $counter > 0 ) {
$ret = $batch->execute(array("w" => 1));
}
?>
In the above, each find() query and insert operation is added to a batch via the .add() method to be sent to the server, in the order provided, for serial execution. So rather than waiting for the write response from the server for each insert, the operations are sent and responded to in batches hence there is less overhead in roundtrips.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With