gpt4 book ai didi

ruby-on-rails - 带有嵌入式文档的 Mongoid 急切加载

转载 作者:行者123 更新时间:2023-12-02 17:33:46 25 4
gpt4 key购买 nike

我的一些类(class):

class User
embeds_many :notifications
field :first_name
field :last_name

def name{ "#{first_name} #{last_name}" }

class Notification
embedded_in :user
belongs_to :sender, class_name: "User", inverse_of: nil

现在在我看来,我实现了一个用于通知的小型邮箱系统。但是,它目前正在访问数据库的 N+1 倍:

<% current_user.notifications.sort{...}.each do |notif|%>
...
<%= notif.sender.name if notif.sender %>

这里的问题是 notif.sender.name 导致 N 命中数据库。我能以某种方式预加载/急切加载这个吗?像 current_user.notifications.includes(:sender) 这样的东西(但会起作用 :D)

我目前只需要发件人姓名。

最佳答案

我认为你在这里运气不好。 Mongoid 有如下错误消息:

Eager loading in Mongoid only supports providing arguments to M.includes that are the names of relations on the M model, and only supports one level of eager loading. (ie, eager loading associations not on the M but one step away via another relation is not allowed).

请特别注意最后一个括号内的句子:

eager loading associations not on the M but one step away via another relation is not allowed

嵌入是一种关系,但您想将 includes 应用于嵌入关系,这对 Mongoid 来说太过分了。

fine manual确实是这样说的:

This will work for embedded relations that reference another collection via belongs_to as well.

但这意味着您将在嵌入关系上调用 includes 而不是嵌入模型的内容。在您的情况下,这意味着您可以为每组嵌入关系急切加载发件人通知:

current_user.notifications.includes(:sender).sort { ... }

这仍然会给您留下 N+1 问题,即预加载应该绕过但您的 N 会更小。

如果这仍然太重,那么您可以将名称反规范化到每个嵌入文档中(即复制它而不是通过 sender 引用它)。当然,如果允许人们更改姓名,则您需要保留副本。

关于ruby-on-rails - 带有嵌入式文档的 Mongoid 急切加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29472487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com