我正在开发一个工具来将一组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();
}
}
}
我遇到问题的部分是将文档的_id
字段转换为十六进制字符串(第43行)。似乎item.get("_id")
返回BSON
类型的对象,其中包含一些转换器:to_string()
返回ObjectId("566740710ed3bc0a8f000001")
,to_json()
返回{"$oid": "566740710ed3bc0a8f000001"}
,这两个都不是我要插入的计划十六进制字符串。我在文档中看到ObjectId
有to_hex()
函数,但我无法弄清楚如何从get()
方法的BSON
返回类型到基础{{} 1}}已实施该方法的类型。
答案 0 :(得分:2)
get()
方法返回Option<&Bson>
。 Bson
是enum
,因此要访问变体中的数据,您需要使用与match
或if 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没有在任何地方发布任何文档。