"mongodb+srv://"がない

クラウドの勉強をしようと思って無料データベースmongoDB Atlasにアカウントを作ってみた。

mongoDBを選んだのは、以下の理由から。

セットアップはサクサクできて、あとはプログラムにconnectするだけ。 もちろん、ちゃんと参考例が表示される。

例えばConnect Your Applicationから辿ったjs用のサンプルはこうなっている。

const MongoClient = require(‘mongodb’).MongoClient;
const uri = "mongodb+srv://<ADMIN>:<PASSWORD>@<MYCLUSTER>.mongodb.net/test?...";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
  const collection = client.db("test").collection("devices");
  // perform actions on the collection object
  client.close();
});

これを真似すれば、非公式クライアントライブラリmongodb 0.3.12を使ったRustのプログラムでも 簡単に移植できるだろうと思ったら、予想が外れてしまった。

thread 'main' panicked at 'failed to auth: OperationError("No servers available for the provide
d ReadPreference.")', src/libcore/result.rs:997:5                                              
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.  

ネットで調べると参考になりそうなのはこのあたり。

そこで、

となって、こういうコードになった:

   let opts = mongodb::ClientOptions::with_unauthenticated_ssl(None, false);
   let uri = <上のURI>;
   let mut m = mongodb::Client::with_uri_and_options(uri, opts).expect("connect");
   client.db("admin").auth("<ADMIN>", "<PASSWORD>").expect("auth");
   let coll = client.db("<DB>").collection("<COLLECTION>");
    ...

しかし、これらを反映してもどうやっても最初のエラーが取れない。

いい加減、諦めかけていたのだけど、Connect with the Mongo Shellの中のサンプルを見ていて 指定すべきURIがMongo Shellのバージョンによって全然違うことに気づいた。 具体的には最新版(3.6 or later)だと、

mongo "mongodb+srv://<CLUSTER>.mongodb.net/test" --username <username>

なのが、3.3 or earlierだとこうなる。

mongo "mongodb://<CLUSTER>-<SHARD0>.mongodb.net:xxx,<CLUSTER>-<SHARD1>.mongodb.net:xxx,<CLUSTER>-<SHARD2>.mongodb.net:xxx/test?...

問題の srv がないじゃん!

なので上のrustプログラムの2行目のuriの定義をこれと入れ替えたら、さっくり通ってしまった。

めでたし、めでたし。