[EXTENSION] directmongosuite

Wow, what a fast answer.

Because i’m using directmongosuite and yiimongodbsuite, I don’t like to define mongo-DB-connection-infomration on different palaces.

So (as i wrote) I use the connectionId from yiimongodbsuiet for driectmongodbsuite. Look at this post #17 http://www.yiiframework.com/forum/index.php/topic/25356-extension-directmongosuite/page__view__findpost__p__142992

To get this work, I (right now) changed your instance method, as you can see:


	public static function instance($connectionId)

	{

		if (!isset(self::$_instance))

			self::$_instance = array();


		if (!isset(self::$_instance[$connectionId]))

		{

			$component = Yii::app()->getComponent($connectionId);


			if ($component instanceof EDMSConnection)

				self::$_instance[$connectionId] = $component;

			else //use YiiMongoDbSuite EMongoDB config

				if ($component instanceof EMongoDB)

				{

					$connection = new EDMSConnection();

					$connection->server = $component->connectionString;

					$connection->dbName = $component->dbName;


	/*next Line: using the replicationSet Parameter from YiiMongoDbSuite config*/


					$connection->options["replicaSet"]=$component->replicaSet;


					if ($component->autoConnect == false)

						$connection->options['connect'] = false;


					self::$_instance[$connectionId] = $connection;

				}

			else

				throw new EDMSException("Invalid connectionId: $connectionId");

		}


		return self::$_instance[$connectionId];

	}

Joblo - is this the right place to implement replacationSets (finally it works right now :slight_smile: ).

I know, that it’s not best practice to change the code of an extension: i better should overwrite the method at an new class. Same think on slaveOkay topic. But the point is: I don’t need to add a new class to overwride your method, if the new release is coming soon.

directmongosuite is opensource, so you can change all for your needs, but you have to compare/change your code on the next release …

Hi all,

@Joblo, compliments for the extension, it works very well :slight_smile:

I’m having problems with sorting when using the extension’s dataprovider with a CListView.

In short, if I turn on the sorting option the page is not rendered.

In my action, I have this configuration for the dataprovider:


$providerConfiguration = array(

        'pagination' => array(

            'pageSize' => 1,

        ),

        'sort' => array(

            'attributes' => array(

                'title',

                'createDate',

                'ratingAverage'

        ))

    );

In my view, this is the definition of my CListView:


$this->widget('zii.widgets.CListView', array(

    'dataProvider' => $searchDataProvider,

    'itemView' => '_searchResult',

    'enablePagination' => TRUE,

    'pager' => array(

        'header' => '',

        'cssFile' => false

    ),

    'pagerCssClass' => 'pagination',

    'enableSorting' => TRUE,

    'sortableAttributes' => array(

        'title' => 'Title',

        'createDate' => 'Date added',

        'ratingAverage' => "rating"

    ),

    'summaryText' => 'We have {count} item/s in {pages} page/s for you',

    'summaryCssClass' => 'results-info',    

    'template' => '{summary} {sorter} {pager} {items} {sorter} {pager}'

));

If I remove the “sortableAttributes” option from the CListView configuration, everything works, but obviously I don’t have any sorting capabilities…

If, instead, I add the "sortableAttributes", the page is rendered up to the place where the sorting links should be placed…

Can you help me?

Thank you very Much,

Riccardo

Needs time to create an example code, debugging and more …

Sorry I’m not able to investigate this issue yet.

You have to wait for or you can try debugging through your and the Yii code of the CListView / Dataprovider.

No problem, I only wanted to know if it was something related to my code. I’ll debug this by myself asap and will keep you up to date. Just for information, have you ever seen the sorting functionality working with a CListView?

Thanks

Riccardo

No, I never tested the sorting feature with a CListView.

I have only added the ‘sort feature’ to the dataprovider and use it once on quering the data.

Did you test CListView sorting with the extension YiiMongoDbSuite?

If this works, the two dataproviders have to be compared.

Or a AR dataprovider has to be compared/debugged to check what’s going on when sorting the CListview and what is not implemented in the directmongosuite dataprovider.

Yes, I’ve worked with YiiMongoDbSuite and CListView, the sorting works as expected. I’ll start from there, comparing the two dataproviders to implement the sorting feature in directmongosuite.

I’ll let you know, thanks for the info.

Riccardo

Hi Joblo,

I have a working implementation of the sorting capability for the EDMSDataProvider. It works exactly as the CArrayDataProvider works, i’m going to test this a little bit more today, do you have a github repo to make a pull? How do you prefer to have the code?

Riccardo

Thanks and congratulations :slight_smile:

You are the first, who offers a fully implemented bugfix/improvement for one of my extentions.

No I don’t have a github account, you can add the code as zip-attachment here or you can mail it to the @author email in the source files.

Once a day I will move my extensions to github, but I need time to learn how to work with github.

Excuse me for the delay Joblo, I’ve just sent you an email with the EDMSDataProvider file attached.

I just starting using this extension and noticed that my session was being finished too quick, after looking at EDMSHttpSession I noticed that the timeout is considered as miliseconds. Why is that?

Shouldn’t it be seconds just as in when using ‘CDbHttpSession’?

Thanks

Please contact aoyagikouhei, the author of this part of the extension.

Hi,

i’m thinking about the following issue and how to solve that by using EDMS.

The point is, that I’m get’s an package of documents from mongo using:


$res=EDMSQuery::instance('mycollection')->findArray(array('matchID'=>$matchID));

than I iterate through the array to change the content of the documents partially:


foreach ($res as $doc)

      {

       $doc['attr']="new content";

       $return[]=$doc;      //hier I add all the docuemtns to an array again

       }



The question is: how to write the changes back to the mongoDB?

Probably one way is to iterate through the array in order to create one mongo request für each $doc. But that is not very efficent.

Is there a way to read a package of data, modify them and write back/update?

Mayby there is already an method for that?

Thank you, rall0r.

The mongoCollection has a method batchInsert.

So for batch inserting you could do


EDMSQuery::instance('mycollection')->getCollection()->batchInsert($array)

.

But AFAIK there exists not ‘batchUpdate’ like batchInsert.

If you want to assign the same value (‘new content’) to an attribute of multiple records you can do


EDMSQuery::instance('mycollection')->update(array('matchID'=>$matchID),array('attr'=>'new content')

.

Otherwise you have to update each record in a single query.

Hi,

I need to use the findAndModify feature from mongoDB in order to read and update an value at one request (which is very usefull, while mongoDB does not support transactions).

http://www.mongodb.org/display/DOCS/findAndModify+Command

Finally this results in using DB Jobs on mongoDB.

Is there a way to trigger something like that on EDMS or to pass trough this to the "low level" php mongoDB commands?

I took a look at your EDMS code, but does not get an idea.

Thank you!

For ‘low level commands’ you have to use:




 Yii::app()->edmsMongoDB()->command(...);

 //or

 EDMSQuery::instance('myCollection')->getDb->command(...);



But if you want you could help me to implement this in the EDMSQuery:

Add a function like below and let me know

  • how it works

  • how to handle the result

  • what order of function params is most useful

  • what default values of the function params are most useful: upsert=true, new=true …?

See EDMSQuery::findDistinct, it uses the db-command too.





public function findAndModify($update,$query = array(),$fields=array(), $upsert=false, $new=false, $remove=false,$sort = array())

    {

        $command = array('findAndModify' => $this->_collectionName,'update'=>$update);


        if (!empty($query))

            $command['query'] = $query;


        if (!empty($fields))

            $command['fields'] = $fields;


        if (!empty($sort))

            $command['sort'] = $sort;


        if ($upsert)

            $command['upsert'] = true;


        if ($new)

            $command['new'] = true;


        if ($remove)

            $command['remove'] = true;




        $result = $this->getDb()->command($command);


        var_dump($result);

        //check how data are returned ..... like in findDistinct <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/huh.gif' class='bbc_emoticon' alt='???' />

        //how to handle the result?


        //$items = $result['ok'] == 1 ? $result['values'] : null;

        //return $items;

    }




@ Joblo

first of all, thank you, for your post. I will handle this topic in the next weeks. I let you know, how i implemented this and if i write an method for EMDS (right now, i think i will try this)

By the way: we are using EMDS with mongoDBsuite connection ID. By changing this to an dedicated EDMSConnection, all Mongo Request are much,much more slower. Rendering-Time of an webpage, which uses EMDS to find some documents, needs 600ms by using EMDSConnection and only 100ms if we use the Yii Mongo suite Connenction Class(EMongoDB)

Do you know how this could be happend?

rall0r

@Joblo i have created an findAndModify method for your EDMSQuery Class.

I have decided to use an array as parameter instead of an placeholder for every parameter

(au you wrote: ($update,$query = array(),$fields=array(), $upsert=false, $new=false, $remove=false,$sort = array()).

The reason is: handling long line of parameter could cause in an error if you (for example) change parameter 6 from false to true instead of parameter 5

Please take a look at the following lines and give me an feedback


	/**

	 * findAndModify a docuemnt http://www.mongodb.org/display/DOCS/findAndModify+Command

	 * @param array $update		--update or remove -> one is required

	 * @param boolean $remove

	 * @param array $query

	 * @param array $fields

	 * @param boolean $upsert

	 * @param boolean $new

	 * @param array $sort

	 * @return boolean

	 * Example for counter - increment the filed counter by 1 and return the new value:

	 * 			EDMSQuery::instance('counterCollection')->findAndModify(

	 * 					array(

	 *					'update'=>array('$inc'=>array('counter'=>1)),

	 *					'query'=>array('_id'=>new MongoId('3fe54eabf6a60c8a31c8570')),

	 *					'upsert'=>true,

	 *					'new'=>true,

	 *						)

	 *					);

	 */

	

	public function findAndModify ($param=array())

	{

		if (!array_key_exists('update',$param) AND !array_key_exists('remove',$param))	//one is required

		{return false;

		}

		

		$collection['findAndModify']=$this->_collectionName;

		$param=array_merge($collection,$param);  

		

		$result = $this->getDb()->command($param);

		$result["lastErrorObject"]["ok"]=1?$return= $result["value"]:$return= false;

		return $return;

	}