diff --git a/server/src/stats.rs b/server/src/stats.rs index f14a73a..3c9dae7 100644 --- a/server/src/stats.rs +++ b/server/src/stats.rs @@ -11,10 +11,16 @@ pub struct CachedStatistics { pub seven_days: Statistics, } +#[derive(Debug, Clone, Deserialize)] +pub struct Aliases { + #[serde(deserialize_with = "alias_de")] + pub aliases: HashMap>, +} + #[derive(Debug, Clone, Deserialize)] pub struct Statistics { pub count: Vec, - #[serde(deserialize_with = "alias_de")] + #[serde(default)] pub aliases: HashMap>, pub duties: Vec, pub hosts: Vec, diff --git a/server/src/web/stats.rs b/server/src/web/stats.rs index b255f9a..e97ea4e 100644 --- a/server/src/web/stats.rs +++ b/server/src/web/stats.rs @@ -3,7 +3,7 @@ use chrono::{Duration, Utc}; use mongodb::bson::{Document, doc}; use mongodb::options::AggregateOptions; use tokio_stream::StreamExt; -use crate::stats::Statistics; +use crate::stats::{Aliases, Statistics}; use crate::web::State; lazy_static::lazy_static! { @@ -15,19 +15,6 @@ lazy_static::lazy_static! { "$count": "count", }, ], - "aliases": [ - { - "$group": { - "_id": "$listing.content_id_lower", - "aliases": { - "$addToSet": { - "name": "$listing.name", - "home_world": "$listing.home_world", - }, - }, - } - } - ], "duties": [ { "$group": { @@ -102,6 +89,26 @@ lazy_static::lazy_static! { } }, ]; + + static ref ALIASES_QUERY: [Document; 1] = [ + doc! { + "$facet": { + "aliases": [ + { + "$group": { + "_id": "$listing.content_id_lower", + "aliases": { + "$addToSet": { + "name": "$listing.name", + "home_world": "$listing.home_world", + }, + }, + } + } + ], + }, + }, + ]; } pub async fn get_stats(state: &State) -> Result { @@ -132,6 +139,28 @@ async fn get_stats_internal(state: &State, docs: impl IntoIterator = stats.hosts.iter().map(|host| host.content_id_lower).collect(); + let mut aliases_query: Vec = ALIASES_QUERY.iter().cloned().collect(); + aliases_query.insert(0, doc! { + "$match": { + "listing.content_id_lower": { + "$in": ids, + } + } + }); + let mut cursor = state + .collection() + .aggregate(aliases_query, AggregateOptions::builder() + .allow_disk_use(true) + .build()) + .await?; + let doc = cursor.try_next().await?; + let doc = doc.ok_or_else(|| anyhow::anyhow!("missing document"))?; + let aliases: Aliases = mongodb::bson::from_document(doc)?; + + stats.aliases = aliases.aliases; + Ok(stats) }