Yesod/持久一对一查询

发布于 2025-01-08 01:01:39 字数 698 浏览 3 评论 0原文

比如说,在 Yesod/Persistent 中,我的模型设置如下:

User
    ident Text
    password Text Maybe
    UniqueUser ident
Question
    title Text
    asker UserId Eq

我有一个 Question 列表,并且想要检索相应的 User 列表。我该怎么做呢?

我考虑过联接,但这些是一对多,而不是一对一(我认为这并不重要,但我想要一个更简单的解决方案)。手动进行连接也是一种选择,但我担心性能 - 我有

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10]
let askerIds = map (\(Entity _ q) -> questionAsker q) questions
askers <- sequence $ map (runDB . get) askerIds
let questionsAndAskers = zip questions askers

,但我担心在 map 中使用 runDB (这不会使每个用户对数据库的单独请求?)

是否有更好/更惯用的方法来实现这一点?

Say, in Yesod/Persistent, I have models setup like so:

User
    ident Text
    password Text Maybe
    UniqueUser ident
Question
    title Text
    asker UserId Eq

And I have a list of Questions, and would like to retrieve the corresponding list of Users. How would I go about doing this?

I've thought about joins, but those are one-to-many, not one-to-one (I suppose it doesn't matter, but I'd like a simpler solution). Manually doing the join is also an option, but I'm worried about performance - I have

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10]
let askerIds = map (\(Entity _ q) -> questionAsker q) questions
askers <- sequence $ map (runDB . get) askerIds
let questionsAndAskers = zip questions askers

but I'm worried about using runDB in the map (wouldn't it make a separate request to the database for each user?)

Is there a better/more idiomatic way to achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

翻了热茶 2025-01-15 01:01:39

我还没有对此进行类型检查,但我会将整个内容放在 runDB 中:

runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10] >>= mapM (\qe@(Entity _ q) -> do
    asker <- get $ questionAsker q
    return (qe, asker))

I haven't type-checked this yet, but I would stick the whole thing inside of runDB:

runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10] >>= mapM (\qe@(Entity _ q) -> do
    asker <- get $ questionAsker q
    return (qe, asker))
南城旧梦 2025-01-15 01:01:39

怎么样:

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10]
let askerIds = map (\(Entity _ q) -> questionAsker q) questions
askers <- runDB $ selectList [UserId <-. askerIds] []
let questionsAndAskers = zip questions askers

看起来应该为用户访问数据库一次。

How about:

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10]
let askerIds = map (\(Entity _ q) -> questionAsker q) questions
askers <- runDB $ selectList [UserId <-. askerIds] []
let questionsAndAskers = zip questions askers

That seems like it should hit the DB once for the users.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文