rust - 在用户不使用N + 1查询的情况下登录时将数据添加到Diesel结果中

标签 rust rust-diesel

我有一个电影数据库,用户可以使用以下模型将电影标记为已观看和收藏的电影:

#[derive(Serialize, Deserialize, Identifiable, Queryable, Associations)]
#[table_name = "movies"]
struct Movie {
    id: 32
}

#[derive(Serialize, Deserialize, Identifiable, Queryable, Associations)]
#[table_name = "users"]
struct User {
    id: 32
}

#[derive(Serialize, Deserialize, Identifiable, Queryable, Associations)]
#[table_name = "favorite_movies"]
struct FavoriteMovie {
    movie_id: i32,
    user_id: i32,
}

#[derive(Serialize, Deserialize, Identifiable, Queryable, Associations)]
#[table_name = "watched_movies"]
struct WatchedMovie {
    movie_id: i32,
    user_id: i32,
    date: DateTime,
}

如果要登录,同时又要避免N + 1查询的问题,该如何处理要列出数据库中最近添加的100部电影并包括每部电影的用户数据的情况?

我在想可以为movies表添加另一个结构,其中还包括可选的用户数据,但是我不确定如何将其与Diesel ORM一起使用。

struct UserData {
   favorite: bool,
   watched: Option<DateTime>,
}

struct UserMovie {
   id: i32,
   user_data: Option<UserData>,
}

最佳答案

使用 left_join :

struct UserMovie {
    movie: Movie,
    favorite_movie: Option<FavoriteMovie>,
    watched_movie: Option<WatchedMovie>,
}

let conn = get_db_connection();
let user_movies: Vec<UserMovie> = movies::table
    .left_join(
        favorite_movies::table.on(favorite_movies::movie_id
            .eq(movies::id)
            .and(favorite_movies::user_id.eq(user_id))),
    )
    .left_join(
        watched_movies::table.on(watched_movies::movie_id
            .eq(movies::id)
            .and(watched_movies::user_id.eq(user_id))),
    )
    .load(conn)?
    .into_iter()
    .map(
        |(movie, favorite_movie, watched_movie): (Movie, Option<FavoriteMovie>, Option<WatchedMovie>)| UserMovie {
            movie,
            favorite_movie,
            watched_movie,
        }
    )
    .collect()

关于rust - 在用户不使用N + 1查询的情况下登录时将数据添加到Diesel结果中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61291050/

相关文章:

rust - 如何使用通过命令行指定的变量来编译库? [复制]

rust - 借用内容的作业

rust - 如何在Rust Diesel中使用时间戳和时间间隔进行算术运算

rust - 如何制作柴油自动生成模型

postgresql - 运行 Diesel CLI 工具时为 "Ordinal Not Found"

rust - 使用动态数量的 .and() 创建 Diesel.rs 查询

rust - 如何检查两个变量是否都是 Some?

rust - 当显式案例不匹配时,如何将枚举扁平化为特例

rust - 如何返回包含通用值的向量

rust - 如何在柴油中实现嵌套过滤器?