如何将actix_web Json存储到mongodb?

时间:2019-09-04 06:19:47

标签: mongodb rust actix-web

尝试使用r2d2-mongodb和actix_web将传入数据存储到mongo中。

#[derive(Serialize, Deserialize, Debug)]
struct Weight {
    desc: String,
    grams: u32,
}

fn store_weights(weights: web::Json<Vec<Weight>>, db: web::Data<Pool<MongodbConnectionManager>>) -> Result<String> {
    let conn = db.get().unwrap();
    let coll = conn.collection("weights");
    for weight in weights.iter() {
        coll.insert_one(weight.into(), None).unwrap();
    }
    Ok(String::from("ok"))
}

我似乎无法理解如何将重量转换为insert_one来使用。 上面的代码错误变成error[E0277]: the trait bound 'bson::ordered::OrderedDocument: std::convert::From<&api::weight::Weight>' is not satisfied

1 个答案:

答案 0 :(得分:0)

signature for insert_one是:

pub fn insert_one(
    &self, 
    doc: Document, 
    options: impl Into<Option<InsertOneOptions>>
) -> Result<InsertOneResult>

Documentbson::Document,是bson::ordered::OrderedDocument的别名。

您的类型Weight没有实现特征Into<Document>,这是weight::into()所必需的。您可以实现它,但是更惯用的方式是将Serialize特性与bson::to_bson一起使用:

fn store_weights(weights: Vec<Weight>) -> Result<&'static str, Box<dyn std::error::Error>> {
    let conn = db.get()?;
    let coll = conn.collection("weights");

    for weight in weights.iter() {
        let document = match bson::to_bson(weight)? {
            Document(doc) => doc,
            _ => unreachable!(), // Weight should always serialize to a document
        };
        coll.insert_one(document, None)?;
    }

    Ok("ok")
}

注释:

  1. to_bson返回一个枚举Bson,可以是ArrayBooleanDocument等。我们使用{{1} },以确保它是match

  2. 我使用Document而不是自动包装来利用?返回类型。确保您的Result类型的错误是Into<Error>

  3. 返回Result而不是为每个请求分配新的&'static str