Skip to main content

mecomp_daemon/services/
radio.rs

1use mecomp_storage::{
2    db::schemas::{
3        RecordId,
4        analysis::Analysis,
5        song::{Song, SongId},
6    },
7    errors::StorageResult,
8};
9use surrealdb::{Connection, Surreal};
10
11use super::get_songs_from_things;
12
13/// Get the 'n' most similar songs to the given list of things
14///
15/// # Errors
16///
17/// Returns an error if there is an issue with the database
18#[inline]
19pub async fn get_similar<C: Connection>(
20    db: &Surreal<C>,
21    things: Vec<RecordId>,
22    n: u32,
23    settings: &mecomp_core::config::AnalysisSettings,
24) -> StorageResult<Vec<Song>> {
25    if things.is_empty() || n == 0 {
26        return Ok(vec![]);
27    }
28
29    // go through the list, and get songs for each thing (depending on what it is)
30    let songs: Vec<SongId> = get_songs_from_things(db, &things)
31        .await?
32        .into_iter()
33        .map(|s| s.id)
34        .collect();
35
36    // whether to use feature-based or embedding-based analysis
37    let use_embeddings = matches!(settings.kind, mecomp_core::config::AnalysisKind::Embedding);
38
39    let analyses = Analysis::read_for_songs(db, songs).await?;
40    let neighbors = Analysis::nearest_neighbors_to_many(db, analyses, n, use_embeddings).await?;
41    Analysis::read_songs(db, neighbors.into_iter().map(|a| a.id).collect()).await
42}