我正在嘗試更新我的檔案,如果我沒有傳遞一個欄位,它將被洗掉。
我的檔案是
{
"_id":"27fc47a4-0730-446c-8acd-41aa6e227406",
"user_id":"a07c8c2f-e83a-47f7-80dc-a18407f997e1",
"pet":{
"name":"Hello",
"bio":"Hello",
"gender":"Male",
"can_live_with_other_cats":true,
"can_live_with_other_dogs":true
},
"status":"Pending",
"created_at":{
"$date":"2021-11-06T22:30:41.977Z"
}
}
我嘗試更新
"pet":{
"name":"Hello",
"bio":"Hello",
"gender":"Male",
},
"status":"Pending",
"created_at":{
"$date":"2021-11-06T22:30:41.977Z"
}
他正在洗掉 "can_live_with_other_cats":true 和 "can_live_with_other_dogs":true
如何在不洗掉我的欄位的情況下更新?
async fn update(&self, adoption: &dto::adoption::update::Adoption) -> Result<(), Error> {
let mongo_collection = MongoClient::get_collection("adoptions").await;
let mongo_model = datamodel::insert_adoption::PetDataModel::from(&adoption.pet);
let query = doc! {"_id": adoption.id.to_string()};
let doc = mongodb::bson::to_document(&mongo_model).unwrap();
println!("{}", doc);
let update = doc!{"$set": {"pet": doc} };
mongo_collection
.update_one(query, update, None)
.await
.map(|_| ())
.map_err(|e| domain::errors::Error::internal_server_error(e.to_string()))
}
我要更新的結構
pub struct PetDataModel {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bio: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gender: Option<GenderDataModel>,
#[serde(skip_serializing_if = "Option::is_none")]
pub can_live_with_other_cats: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub can_live_with_other_dogs: Option<bool>,
}
非常感謝
uj5u.com熱心網友回復:
$set使用根據示例傳遞物件提供的值覆寫pet鍵將使用不包含鍵的提供的物件覆寫鍵。
"pet":{
"name":"Hello",
"bio":"Hello",
"gender":"Male"
},
"status":"Pending",
"created_at":{
"$date":"2021-11-06T22:30:41.977Z"
}
要在不覆寫現有密鑰的情況下進行更新,您可以使用以下格式顯示
例如:
"pet.name":"Hello",
"pet.bio":"Hello",
"pet.gender":"Male"
"pet.status":"Pending",
"pet.created_at.$date": "2021-11-06T22:30:41.977Z"
正如@Renato 在評論中所述,我們也可以使用 serterename屬性
pub struct PetDataModel {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "pet.name")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "pet.bio")]
pub bio: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "pet.gender")]
pub gender: Option<GenderDataModel>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "pet.can_live_with_other_cats")]
pub can_live_with_other_cats: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "pet.can_live_with_other_dogs")]
pub can_live_with_other_dogs: Option<bool>,
}
或者
您可以使用此代碼rust-flatten-json來展平 json
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate error_chain;
use serde_json::value::Value;
use serde_json::map::Map;
error_chain! {
foreign_links {
Json(::serde_json::Error);
}
}
pub fn flatten(nested_value: &Value, flat_value: &mut Value, parent_key: Option<String>, infer_type: bool, separator: Option<&str>) -> Result<()> {
// if object
if let Some(nested_dict) = nested_value.as_object() {
flatten_object(flat_value, &parent_key, nested_dict, infer_type, separator)?;
} else if let Some(v_array) = nested_value.as_array() {
let new_k = parent_key.unwrap_or_else(||String::from(""));
flatten_array(flat_value, &new_k, v_array, infer_type, separator)?;
} else {
error!("Expected object, found something else: {:?}", nested_value)
}
Ok(())
}
fn flatten_object(flat_value: &mut Value, parent_key: &Option<String>, nested_dict: &Map<String, Value>, infer_type: bool, separator: Option<&str>) -> Result<()> {
let sep = if let Some(sep) = separator {
sep
} else {
"."
};
for (k, v) in nested_dict.iter() {
let new_k = match parent_key {
Some(ref key) => format!("{}{}{}", key, sep, k),
None => k.clone()
};
// if nested value is object recurse with parent_key
if let Some(obj) = v.as_object() {
flatten_object(flat_value, &Some(new_k), obj, infer_type, separator)?;
// if array
} else if let Some(v_array) = v.as_array() {
// if array is not empty
if !v_array.is_empty() {
// traverse array
flatten_array(flat_value, &new_k, v_array, infer_type, separator)?;
// if array is empty insert empty array into flat_value
} else if let Some(value) = flat_value.as_object_mut() {
let empty: Vec<Value> = vec!();
value.insert(k.to_string(), json!(empty));
}
// if no object or array insert value into the flat_value we're building
} else if let Some(value) = flat_value.as_object_mut() {
infer_type_and_insert(v, new_k, value, infer_type)?;
}
}
Ok(())
}
fn infer_type_and_insert(v: &Value, new_k: String, value: &mut Map<String, Value>, infer_type: bool) -> Result<()> {
let new_val;
if infer_type {
if let Some(string) = v.as_str() {
new_val = match string.parse::<i64>() {
Ok(i) => serde_json::to_value(i)?,
Err(_) => match string.parse::<f64>() {
Ok(f) => serde_json::to_value(f)?,
Err(_) => match string.parse::<bool>() {
Ok(b) => serde_json::to_value(b)?,
Err(_) => serde_json::to_value(string)?
}
}
};
} else {
new_val = v.clone();
}
} else {
new_val = v.clone();
};
value.insert(new_k, new_val);
Ok(())
}
fn flatten_array(flat_value: &mut Value, new_k: &str, v_array: &[Value], infer_type: bool, separator: Option<&str>) -> Result<()> {
for (i, obj) in v_array.iter().enumerate() {
let array_key = format!("{}.{}", new_k, i);
// if element is object or array recurse
if obj.is_object() | obj.is_array() {
flatten(obj, flat_value, Some(array_key), infer_type, separator)?;
// else insert value in the flat_value we're building
} else if let Some(value) = flat_value.as_object_mut() {
infer_type_and_insert(obj, array_key, value, infer_type)?;
}
}
Ok(())
}
let value: Value = match serde_json::from_str(&input) {
Ok(value) => value,
Err(e) => {
error!("{}", &input);
panic!("{}", e);
}
};
let mut flat_value: Value = json!({});
flatten(&value, &mut flat_value, None, true, None)?;
serde_json::to_string(&flat_value)?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/354250.html
