[EXTENSION] directmongosuite A collection of components for the mongoDB
#1
Posted 01 November 2011 - 05:09 PM
#2
Posted 01 November 2011 - 11:17 PM
Joblo, on 01 November 2011 - 05:09 PM, said:
i am interested to this extension
before download it i always to read the source code first .
#3
Posted 02 November 2011 - 03:41 AM
There is the directmongosuite.0.1.zip ready for download (only 22KB).
You don't have to install it if you don't want.
#4
Posted 02 November 2011 - 08:31 PM
'CException' with message 'Property "EDMSLogViewer.db" is not
defined.' on line 254 of EDMSLogViewer.php.
Looks like you just need to re-implement the creation of the capped collection using your new DB connections.
#5
Posted 03 November 2011 - 01:50 AM
Fixed and extension updated.
#6
Posted 04 November 2011 - 11:15 PM
in EDMSQuery class this function has wrong result:
public function findArray($criteria=array(),$select=array(),$sort=array(),$limit=null)
{
$result = array();
$cursor = $this->findCursor($criteria,$select,$sort,$limit);
if (!empty($cursor) && $cursor->count())
foreach ($cursor as $id => $value)
$result[] = array();
return $result;
}
$result[] = array(); //you must do something wrong here
may be it should be : $result[] = $value;
#7
Posted 05 November 2011 - 04:21 AM
Added findCountBy and some minor changes.
#8
Posted 06 November 2011 - 09:59 AM
this function in EDMSQuery should be modified to :
public static function modelToArray($model)
{
if (method_exists($model, 'getAttributes'))
return $model->getAttributes(); //set model attributes with no validation
else
{ //assign the values to the public properties
$class = new ReflectionClass(get_class($model));
$attributes = array();
foreach ($class->getProperties() as $property)
{
if ($property->isPublic() && !$property->isStatic()) {
$key = $property->getName();
$attributes[$key] = $model->$key;
}
}
return $attributes;
}
}
now your 's :
...
$class=new ReflectionClass(get_class($model));
$attributes = array();
foreach($model->getProperties() as $property)
{
if($property->isPublic() && !$property->isStatic())
{
$key=$property->getName();
$attributes[$key] = $model->$key;
}
}
change the $model->getProperties =====> $class->getProperties
#9
Posted 06 November 2011 - 02:49 PM
Please take a look at this latest version.
The function EDMSQuery::arrayToModel and EDMSDataProvider::fetchData has been changed there for a better performance.
If using non CModel classes the model properties should not be analyzed (new ReflectionClass) for each row on fetching data.
#10
Posted 06 November 2011 - 10:02 PM
Joblo, on 06 November 2011 - 02:49 PM, said:
Please take a look at this latest version.
The function EDMSQuery::arrayToModel and EDMSDataProvider::fetchData has been changed there for a better performance.
If using non CModel classes the model properties should not be analyzed (new ReflectionClass) for each row on fetching data.
well done joblo , great extension !
#11
Posted 16 January 2012 - 10:25 AM
great extension.
I'd like to ask you for assistance in setting authmanager.
I've looked through the source of EDMSAuthManager, and I am not able to understand where the authorization rules are saved to.
I have the following set up in my config/main.php:
//uses the collection 'edms_authmanager' for the authmanager
'authManager' => array(
'class' => 'EDMSAuthManager',
'connectionId' => 'mongodb'
),
Yet, when I save my authorization rules, I do not see the collection in my mongodb nor the file in protected/data/auth.php
Is there something I should check first, can someone post their successful configuration if they moved to mongodb for their auth rules?
Thanks!
#12
Posted 16 January 2012 - 12:57 PM
It wasn't showing anything in my collections because I forgot to add "Save" to my authorization rules. That was the only difference between PhpAuth and the DbAuth way of doing things.
Again, awesome extension!
#13
Posted 23 January 2012 - 03:02 AM
Have been using directmongosuite with yiimongodbsuite and both tend to work well together without any problem so far.
#14
Posted 03 February 2012 - 04:45 AM
I have tow questions:
1.) how to set slaveOkay=true? -> http://www.php.net/m...etslaveokay.php
Or is it on by default?
2.) how to realize updates with multiple operators, like:
{ $set : { x : 1 }, $inc : { y : 1 } }Is there something like an wiki, where I can write down my examples? Maybe other users (which starts with mongoDB) has the same questions?!
Thank you.
#15
Posted 03 February 2012 - 08:49 AM
I decided change the atomicUpdate method in order to have to possibility to process different modifier at one mongo request:
public function atomicUpdate($criteria,$values,$modifier = '$set', $multiple = false,$options=array())
{
if (empty($values) and !is_array($modifier))
return false;
if(is_array($modifier)) {$action=$modifier;}
else {$action = array($modifier => $values);}
if ($multiple)
$options = array_merge($options, array('multiple'=>true));
return $this->getCollection()->update($criteria,$action,$options);
}That means, you can leave $values empty and use $modifier as an array with the following layout:
array($modifier1 => array($field1=>$value1, $field2=>$value2), $modifier2=> array($field3=>$value5,));
Could that be an valid solution?
#16
Posted 24 February 2012 - 06:05 AM
1.) SlaveOK is true by default, but in the next release (coming soon) there will be a solution for that too.
2.) Thanks for the input, I will change the code like this
#17
Posted 12 March 2012 - 11:24 AM
right now we are using directmongosuite and yiimongodbsuite side by side, which works well on an MongoDB replication set.
directmongosuite is using the connection settings from the yiimongodbsuite:
'behaviors' => array(
'edms' => array(
'class'=>'EDMSBehavior',
'connectionId' => 'mongodb',
'debug'=>true //for extended logging
)
),
[....]
/*yiimongodbsuite zeugs*/
'mongodb' => array(
'class' => 'EMongoDB',
'connectionString' => 'mongodb://server1,server2',
'replicaSet' => 'replSet_RS',
'dbName' => 'testdb',
'fsyncFlag' => true,
'safeFlag' => true,
'useCursor' => false
),
Some hours before we did some changes on the Primary/Secondary configuration for the MongoDB.
All the application components, which are using yiimongodbsuite working without any errors with this new configuration.
All the application components using directmongosuite gets the following error:
Quote
at this point:
305 public function findOne($criteria,$select=array())
306 {
307 //always add the '_id'
308 if (!empty($select) && !in_array('_id',$select))
309 array_push($select,'_id');
310
311 $cursor = $this->getCollection()->findOne($criteria, $select); <---here
312
313 return !empty($cursor) ? $cursor : false;
314 }May you have any idea what is goning on here?
Thank you, rall0r.
#18
Posted 13 March 2012 - 02:41 AM
If you google for 'mongodb slaveok php' you will find a lot of information about this.
It seems you try to read from a secondary without setSlaveOk = true.
See the mongodb manual and the php manual.
You have to configure the options of the edms-component with 'replicaSet'=>...
Maybe you have to add ->setSlaveOkay in the code of the 'function edmsMongoDb' of the file EDMSBehavior.
In the next release (coming soon) if have added a property 'setSlaveOkay' so that you can configure this call in the config/main.php.
But how did you configure the yiimongodbsuite with replicaSet=...?
As I can see in the source, the replicaSet-option is not available in EMongoDb.php from yiimongodbsuite.
Where is setSlaveOkay is set in the yiimongodbsuite?
I can't find this in the source.
Please compare the codes from EMongoDb.php and EDMSConnection.php and how 'new Mongo' is called.
#19
Posted 13 March 2012 - 03:41 AM
Quote
right. But the point is: not to read from slave, becaus by using replicaSets, the PHP-mongoDB driver has to choose the master/primary. (i think so)
Quote
ups.. i forget, that I modified the getConnection() method from yiimongodbsuite. Probably this is the point, why yiimongodbsuite works and directmongosuite doesn't.
My new getConnetion method from yiimongodbsuite looks like that:
public function getConnection()
{
if($this->_mongoConnection === null)
{
try
{
Yii::trace('Opening MongoDB connection', 'ext.MongoDb.EMongoDB');
if(empty($this->connectionString))
throw new EMongoException(Yii::t('yii', 'EMongoDB.connectionString cannot be empty.'));
if($this->persistentConnection !== false)
$this->_mongoConnection = new Mongo($this->connectionString, array(
'connect'=>$this->autoConnect,
'persist'=>$this->persistentConnection,
'replicaSet'=>$this->replicaSet <--- added this
));
else
$this->_mongoConnection = new Mongo($this->connectionString, array(
'connect'=>$this->autoConnect,
'replicaSet'=>$this->replicaSet <--- added this
));
return $this->_mongoConnection;
}
catch(MongoConnectionException $e)
{
throw new EMongoException(Yii::t(
'yii',
'EMongoDB failed to open connection: {error}',
array('{error}'=>$e->getMessage())
), $e->getCode());
}
}
else
return $this->_mongoConnection;
}
So i thought this configuration...
'behaviors' => array(
'edms' => array(
'class'=>'EDMSBehavior',
'connectionId' => 'mongodb',
'debug'=>true //for extended logging
)
),
..will work with replicaSets too, because yiimogodbsuite does - which is wrong, because directmongosuite "only" takes the connection-information, but not the connection method (logisch :-/ )
So I have to add 2 things at directmongosuite :
1.) slaveOk=true <- in order to read from slave if the slave is "closer" than the master and
2.) replicaSet configuration to the code from directmongosuite
..right?!?
#20
Posted 13 March 2012 - 03:51 AM
The options array is used when calling 'new Mongo(...)'.
'components'=>array(
//configure the mongodb connection
//set the values for server and options analog to the constructor
//Mongo::__construct from the PHP manual
'edms' => array(
'class' => 'EDMSConnection',
'dbName' => 'testdb',
'options' => array('replicaSet'=>....);
),
setSlaveOk is supported in the next release, so you have to change the EDMSBehavior.php to something like below.
Then you can configure the behavior to setSlaveOkay=true in config/main.php
This is a preview of v2.5 ....
class EDMSBehavior extends CBehavior
{
/**
* The connection id for config in config/main
* @var string
*/
public $connectionId = 'edms';
/**
* Set Mongo::setSlaveOkay after creating Mongo if set
* @var boolean
*/
public $setSlaveOkay = null; //<---------------- add this property
/**
* Get edmsMongoDb instance
* @since v1.0
*/
public function edmsMongoDb($dbName=null,$connectionId = null)
{
if (empty($dbName))
$dbName = $this->edmsGetDbName($connectionId);
if (empty($connectionId))
$connectionId = $this->edmsGetConnectionId();
if (!isset(self::$_db))
self::$_db = array();
if (!isset(self::$_db[$connectionId][$dbName]))
{
if ($this->edmsIsDebugMode())
self::edmsLog("Selecting db: $connectionId.$dbName","edms.debug.db.$dbName.$connectionId");
$mongo = $this->edmsMongo($connectionId);
if(isset($this->setSlaveOkay))
$mongo->setSlaveOkay($this->setSlaveOkay);
self::$_db[$connectionId][$dbName] = $mongo->selectDB($dbName);
}
return self::$_db[$connectionId][$dbName];
}

Help












