Yii2: mongodb\Connection not understand dsn

Created on 2 Oct 2014  路  13Comments  路  Source: yiisoft/yii2

hi,
not all dsn work
for example

mongodb://db1.example.net,db2.example.net:2500/database?replicaSet=test&connectTimeoutMS=300000
mongodb bug

Most helpful comment

I do not understand question

Try following configuration:

'mongodb' => [
            'class' => 'yii\mongodb\Connection',
            'dsn'=> 'mongodb://localhost/database?connectTimeoutMS=300000',
            'defaultDatabaseName' => 'database', // Avoid autodetection of default database name
        ],

Detection of the default database name does not changes a 'dsn' value. If it is the reason of your problems it actually should throw exception while attempt to select database, but not while opening connection.

All 13 comments

What do you mean 'not work': is there a particular error message?

yes, it trying to select database with name "database?replicaSet=test&connectTimeoutMS=300000"

#2 /opt/filestore/vendor/yiisoft/yii2-mongodb/Connection.php(134): yii\mongodb\Connection->selectDatabase('filestore?repli...')
Next exception 'yii\mongodb\Exception' with message 'No candidate servers found' in /opt/filestore/vendor/yiisoft/yii2-mongodb/Connection.php:252
Stack trace:
#0 /opt/filestore/vendor/yiisoft/yii2-mongodb/Connection.php(168): yii\mongodb\Connection->open()
#1 /opt/filestore/vendor/yiisoft/yii2-mongodb/Connection.php(134): yii\mongodb\Connection->selectDatabase('filestore?repli...')
#2 /opt/filestore/vendor/yiisoft/yii2-mongodb/Connection.php(191): yii\mongodb\Connection->getDatabase()
#3 /opt/filestore/vendor/yiisoft/yii2-mongodb/ActiveQuery.php(206): yii\mongodb\Connection->getCollection('files')
#4 /opt/filestore/vendor/yiisoft/yii2-mongodb/Query.php(116): yii\mongodb\ActiveQuery->getCollection(NULL)
#5 /opt/filestore/vendor/yiisoft/yii2-mongodb/ActiveQuery.php(125): yii\mongodb\Query->buildCursor(NULL)
#6 /opt/filestore/vendor/yiisoft/yii2-mongodb/Query.php(211): yii\mongodb\ActiveQuery->buildCursor(NULL)
#7 /opt/filestore/vendor/yiisoft/yii2-mongodb/ActiveQuery.php(165): yii\mongodb\Query->one(NULL)
#8 /opt/filestore/vendor/yiisoft/yii2/db/BaseActiveRecord.php(136): yii\mongodb\ActiveQuery->one()
#9 /opt/filestore/vendor/yiisoft/yii2/db/BaseActiveRecord.php(101): yii\db\BaseActiveRecord::findByCondition(Array, true)

but when I specifie replicaSet and connectTimeoutMS through "options", then all work normally

Are you able to connect with this DSN using plain MongoDB PHP extension?

yii2-mongo:

        'mongodb' => [
            'class' => 'yii\mongodb\Connection',
            'dsn'=> 'mongodb://localhost/database?connectTimeoutMS=300000',
        ],
        /** @var Connection $mongo */
        $mongo = Yii::$app->mongodb;
        $mongo->database->mongoDb->selectCollection('xxx')->insert(['a'=>1]);
localhost:27017: Invalid ns [database?connectTimeoutMS=300000.$cmd]

MongoClient

        $mongo = new \MongoClient('mongodb://localhost/database?connectTimeoutMS=300000');
        $mongo->selectCollection('database', 'xxx')->insert(['a'=>1]);
> use database;
switched to db database
> db.xxx.find();
{ "_id" : ObjectId("542d5fa95a8561a808000029"), "a" : 1 }

Hard to say: yii\mongodb\Connection does not change dsn anyhow.
The exception stack you provided shows error occurs on MongoClient instantiation.
This is weird...

http://docs.mongodb.org/manual/reference/connection-string/

This solution maybe more correct:

/^mongodb:\\/\\/.+\\/(.+)(?:$|\?)/sU

or

/^mongodb:\\/\\/.+\\/([^\?]+)/s

Does everything works fine in your case, If you specify Connnection::defaultDatabaseName explictely?

Hmm, I do not understand question,
it thins it will work as well as intended..

I do not understand question

Try following configuration:

'mongodb' => [
            'class' => 'yii\mongodb\Connection',
            'dsn'=> 'mongodb://localhost/database?connectTimeoutMS=300000',
            'defaultDatabaseName' => 'database', // Avoid autodetection of default database name
        ],

Detection of the default database name does not changes a 'dsn' value. If it is the reason of your problems it actually should throw exception while attempt to select database, but not while opening connection.

Do not need try this. When database specified, problem code was not executed.

    protected function fetchDefaultDatabaseName()
    {
        if ($this->defaultDatabaseName === null) {
            if (isset($this->options['db'])) {
                $this->defaultDatabaseName = $this->options['db'];
            } elseif (preg_match('/^mongodb:\\/\\/.+\\/(.+)$/s', $this->dsn, $matches)) {
                $this->defaultDatabaseName = $matches[1];
            } else {
                throw new InvalidConfigException("Unable to determine default database name from dsn.");
            }
        }

        return $this->defaultDatabaseName;
    }

But regexp not correct matching databasename in some cases when database specified throug dsn.

Issue resolved by commit 3abefac

Was this page helpful?
0 / 5 - 0 ratings