如何将Rust Mongo驱动程序的BSON类型转换为ObjectId?

时间:2016-01-28 19:58:09

标签: mongodb rust

我正在开发一个工具来将一组Mongo文档同步到Postgres数据库:

extern crate bson;
extern crate mongodb;
use mongodb::{Client, ThreadedClient};
use mongodb::db::ThreadedDatabase;

extern crate docopt;
use docopt::Docopt;

extern crate postgres;
use postgres::{Connection, SslMode};

static USAGE : &'static str = "
USAGE: user_importer  --mongo-url <mongo_url> --pg-url <pg_url>
       user_importer (--help)

Options:
  --mongo-url  Mongo Connection URI to the DB that has to users to be imported
  --pg-url   Postgres Connection URI to mizuna's DB
  -h, --help        Show this message
";

fn main() {
  let argv = std::env::args();
  let args = Docopt::new(USAGE).and_then(|d| d.argv(argv).parse()).unwrap_or_else(|e| e.exit());

  let mongo_url = args.get_str("<mongo_url>");
  let pg_url = args.get_str("<pg_url>");

  let pg = Connection::connect(pg_url, SslMode::None).unwrap();
  let stmt = pg.prepare("INSERT INTO mongo_users (mongo_id, email, name, sfdc_id) VALUES ($1, $2, $3, $4)").unwrap();

  let mongo = Client::with_uri(mongo_url)
             .ok().expect("Failed to initialize client.");
  let coll = mongo.db("napa").collection("users");
  let cursor = coll.find(None, None).unwrap();

  for result in cursor {
    if let Ok(item) = result {
      println!("{:?}", item.get("_id").unwrap());
      println!("to_string {:?}", item.get("_id").unwrap().to_string());
      println!("to_json {:?}", item.get("_id").unwrap().to_json());
      let mongo_id  = item.get("_id").unwrap().to_string();
      let email     = item.get("email").map(|s| s.to_string());
      let name      = item.get("name").map(|s| s.to_string());
      let sfdc_id   = item.get("sfdc_id").map(|s| s.to_string());


      stmt.execute(&[&mongo_id, &email, &name, &sfdc_id]).unwrap();
    }
  }
}

Playground

我遇到问题的部分是将文档的_id字段转换为十六进制字符串(第43行)。似乎item.get("_id")返回BSON类型的对象,其中包含一些转换器:to_string()返回ObjectId("566740710ed3bc0a8f000001")to_json()返回{"$oid": "566740710ed3bc0a8f000001"},这两个都不是我要插入的计划十六进制字符串。我在文档中看到ObjectIdto_hex()函数,但我无法弄清楚如何从get()方法的BSON返回类型到基础{{} 1}}已实施该方法的类型。

2 个答案:

答案 0 :(得分:2)

get()方法返回Option<&Bson>Bsonenum,因此要访问变体中的数据,您需要使用与matchif let匹配的模式。

let mongo_id  =
  match *item.get("_id").unwrap() {
    Bson::ObjectId(oid) => oid,
    _ => panic!("_id is not an ObjectId!"),
  };

这会使mongo_id字段的ObjectId值初始化_id

答案 1 :(得分:2)

使用OrderedDocument::get_object_id()方法:

let mongo_id = item.get_object_id("_id").unwrap();
let mongo_id_hex = mongo_id.to_hex();

令人遗憾的是,bson-rs没有在任何地方发布任何文档。