feat(mongo): improve completion and add distinct support
This commit is contained in:
1 parent
5bcad3adc6
commit
640e82cdc6
19 files changed
+1865
-275
No files matched your search
@@ -767,6 +767,38 @@ pub async fn aggregate_documents(
|
||||
Ok(MongoDocumentResult { documents, raw_documents: None, extended_documents: Some(extended_documents), total })
|
||||
}
|
||||
|
||||
/// Distinct values of a field, matching the mongo shell's `db.coll.distinct(field, filter)`:
|
||||
/// array fields contribute their elements rather than the whole array, and the server may
|
||||
/// answer from an index with a DISTINCT_SCAN. Values are returned in the `documents` slot as
|
||||
/// bare scalars, which `mongoDocumentsToQueryResult` already renders as a single column.
|
||||
pub async fn distinct(
|
||||
client: &Client,
|
||||
database: &str,
|
||||
collection: &str,
|
||||
field: &str,
|
||||
filter: Option<&str>,
|
||||
) -> Result<MongoDocumentResult, String> {
|
||||
if field.trim().is_empty() {
|
||||
return Err("Distinct field name is required".to_string());
|
||||
}
|
||||
|
||||
let filter_doc: Document = match filter {
|
||||
Some(f) if !f.trim().is_empty() => {
|
||||
let json: serde_json::Value = serde_json::from_str(f).map_err(|e| format!("Invalid filter JSON: {e}"))?;
|
||||
json_filter_to_document(&json)?
|
||||
}
|
||||
_ => doc! {},
|
||||
};
|
||||
|
||||
let col = client.database(database).collection::<Document>(collection);
|
||||
let values = col.distinct(field, filter_doc).await.map_err(|e| e.to_string())?;
|
||||
let documents = values.iter().map(bson_to_json).collect::<Vec<_>>();
|
||||
let extended_documents = values.into_iter().map(|value| value.into_relaxed_extjson()).collect::<Vec<_>>();
|
||||
let total = documents.len() as u64;
|
||||
|
||||
Ok(MongoDocumentResult { documents, raw_documents: None, extended_documents: Some(extended_documents), total })
|
||||
}
|
||||
|
||||
pub async fn create_index(
|
||||
client: &Client,
|
||||
database: &str,
|
||||
|
||||
@@ -257,6 +257,24 @@ pub async fn mongo_aggregate_documents_core(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn mongo_distinct_core(
|
||||
state: &AppState,
|
||||
connection_id: &str,
|
||||
database: &str,
|
||||
collection: &str,
|
||||
field: &str,
|
||||
filter: Option<&str>,
|
||||
) -> Result<MongoDocumentResult, String> {
|
||||
ensure_document_pool(state, connection_id).await?;
|
||||
let connections = state.connections.read().await;
|
||||
match connections.get(connection_id).ok_or("Not found")? {
|
||||
PoolKind::MongoDb(client) => mongo_driver::distinct(client, database, collection, field, filter).await,
|
||||
// The legacy agent protocol has no distinct method and no read that could stand in for it.
|
||||
PoolKind::Agent(_) => Err("MongoDB legacy agent does not support distinct".to_string()),
|
||||
_ => Err("Not a MongoDB connection".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn mongo_create_index_core(
|
||||
state: &AppState,
|
||||
connection_id: &str,
|
||||
|
||||
Reference in new issue
Block a user