hi,
not all dsn work
for example
mongodb://db1.example.net,db2.example.net:2500/database?replicaSet=test&connectTimeoutMS=300000
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...
Do you not correct matching default database
https://github.com/yiisoft/yii2-mongodb/blob/master/Connection.php#L151
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
Most helpful comment
Try following configuration:
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.