feat(mongodb): improve GridFS manager filtering and sorting

* docs: add GridFS manager filter and sort design

* feat: improve GridFS manager filtering and sorting
This commit is contained in:
LSD authored and GitHub committed 2026-07-06 17:17:33 +08:00
1 parent 26647ff755
commit fa5e55a376
14 files changed
+1294 -40

No files matched your search

+35 -2
View File
@@ -207,12 +207,15 @@ pub async fn list_gridfs_files(
client: &Client,
database: &str,
bucket: &str,
filter: Option<&str>,
sort: Option<&str>,
) -> Result<Vec<MongoGridFsFileInfo>, String> {
let bucket = normalized_gridfs_bucket_name(bucket)?;
let collection_name = format!("{bucket}.files");
let collection = client.database(database).collection::<Document>(&collection_name);
let mut cursor =
collection.find(doc! {}).sort(doc! { "uploadDate": -1_i32, "_id": -1_i32 }).await.map_err(|e| e.to_string())?;
let filter_doc = gridfs_file_filter_document(filter)?;
let sort_doc = gridfs_file_sort_document(sort)?;
let mut cursor = collection.find(filter_doc).sort(sort_doc).await.map_err(|e| e.to_string())?;
let mut files = Vec::new();
while cursor.advance().await.map_err(|e| e.to_string())? {
let doc = cursor.deserialize_current().map_err(|e| e.to_string())?;
@@ -221,6 +224,26 @@ pub async fn list_gridfs_files(
Ok(files)
}
fn gridfs_file_filter_document(filter: Option<&str>) -> Result<Document, String> {
match filter {
Some(raw) if !raw.trim().is_empty() => {
let json: serde_json::Value = serde_json::from_str(raw).map_err(|e| format!("Invalid filter JSON: {e}"))?;
json_filter_to_document(&json)
}
_ => Ok(doc! {}),
}
}
fn gridfs_file_sort_document(sort: Option<&str>) -> Result<Document, String> {
match sort {
Some(raw) if !raw.trim().is_empty() => {
let json: serde_json::Value = serde_json::from_str(raw).map_err(|e| format!("Invalid sort JSON: {e}"))?;
json_object_to_document(&json).map_err(|e| format!("Invalid sort: {e}"))
}
_ => Ok(doc! { "uploadDate": -1_i32, "_id": -1_i32 }),
}
}
pub async fn gridfs_bucket_summary(
client: &Client,
database: &str,
@@ -1583,6 +1606,16 @@ mod tests {
assert_eq!(info.aliases, Some(vec!["archive".to_string(), "nightly".to_string()]));
}
#[test]
fn gridfs_file_sort_uses_upload_date_desc_by_default() {
assert_eq!(gridfs_file_sort_document(None).unwrap(), doc! { "uploadDate": -1_i32, "_id": -1_i32 });
}
#[test]
fn gridfs_file_sort_parses_explicit_sort_json() {
assert_eq!(gridfs_file_sort_document(Some(r#"{"filename":1}"#)).unwrap(), doc! { "filename": 1_i64 });
}
#[test]
fn json_object_to_document_parses_find_projection() {
let value = serde_json::json!({