У меня есть Post
схема с виртуальным полем children
, которую я сейчас заполняю, выполнив второй запрос после первого получения моего Post
.
Начального запроса для получения Post
:
post = Post |> Repo.get(id)
затем я запускаю второй запрос, чтобы получить его дочерние элементы и обновить виртуальное поле children
:
children_query =
from(p in Post,
where: fragment("hierarchy <@ ?", ^post.hierarchy),
order_by: p.inserted_at
)
children = Repo.all(children_query)
post = Map.merge(post, %{children: children})
Поле иерархии сохраняется как Ltree в БД и имеет тип :string
в схеме.
Можно ли как-нибудь объединить эти запросы в один?Я пытался работать с функцией Ecto subquery / 2 , но не смог ее обработать.
Я пытался это сделать, но не мог понять, как передать Post
(р в этом случае) в дочерний подзапрос, не получая сообщение об ошибке the variable p is undefined
в строке соединения.
def children_query(post) do
from p in Post,
where: fragment("hierarchy <@ ?", ^post.hierarchy),
order_by: v.inserted_at
end
def get_post(p_id) do
from(p in Post,
where: p.id == ^p_id,
join: c in subquery(children_query(p)),
on: p.id == c.id, # not sure how it would join on
select: %{p | children: c}
)
end
Я хочу выяснить это, потому что это становится очень неэффективным при отображении индексной страницы Post
и необходимость запуска дополнительного дочернего запроса для каждого сообщения в списке.