可以编写一个联合多个表的 Ecto 查询而不写原始 SQL 吗?
Possible to write an Ecto query that unions multiple tables without writing raw SQL?
背景:
我正在编写一个简单的 Q/A 网站。与 Whosebug 非常相似,在此站点中,用户可以 like/upvote 提出问题、回答或评论。
问题:
我正在努力编写一个 Ecto 查询,该查询可以 return 用户 liked/upvoted 的所有问题、答案或评论 liked/upvoted。
具体来说,我想编写一个查询:
- Returns 由特定用户作为单个列表投票的所有问题、评论和答案
- 问题、答案和评论列表按投票时间排序
这个查询似乎需要 UNION,根据我的理解,这是 not yet supported by ecto 2.0。
因此,我想知道是否有人可以向我展示或指出在 Ecto 中处理此类查询的正确方向。感谢您的任何帮助。
以下是相关模型的架构。
...
schema "users" do
...
has_many :answer_upvotes, AnswerUpvote
has_many :comment_upvotes, CommentUpvote
has_many :question_upvotes, QuestionUpvote
many_to_many :upvoted_answers, Answer, join_through: AnswerUpvote
many_to_many :upvoted_comments, Comment, join_through: CommentUpvote
many_to_many :upvoted_questions, Question, join_through: QuestionUpvote
timestamps
end
...
schema "answer_upvotes" do
belongs_to :answer, Answer
belongs_to :user, User
timestamps
end
...
schema "comment_upvotes" do
belongs_to :comment, Comment
belongs_to :user, User
timestamps
end
...
schema "question_upvotes" do
belongs_to :question, Question
belongs_to :user, User
timestamps
end
...
schema "questions" do
...
belongs_to :user, User
has_many :answers, Answer
has_many :upvotes, QuestionUpvote
many_to_many :upvoting_users, User, join_through: QuestionUpvote
timestamps
end
...
schema "answers" do
...
belongs_to :question, Question
belongs_to :user, User
has_many :comments, Comment
has_many :upvotes, AnswerUpvote
many_to_many :upvoting_users, User, join_through: AnswerUpvote
timestamps
end
...
schema "comments" do
...
belongs_to :answer, Answer
belongs_to :user, User
has_many :upvotes, CommentUpvote
many_to_many :upvoting_users, User, join_through: CommentUpvote
timestamps
end
编辑
我可以编写一个查询来按投票日期分别对问题、答案或项目进行排序。
例如:
upvoted_answers_query =
from answer in Answer,
join: upvote in assoc(answer, :upvotes), where: upvote.user_id == ^user.id,
order_by: upvote.inserted_at
select: answer
但我不确定如何编写一个单一的 Ecto 查询,无需使用联合或编写原始 SQL。
目前不支持,但有一个开放的工单:https://github.com/elixir-ecto/ecto/issues/1549
Ecto v3.0.0 (2018-10-29) 添加了对 union
和 union_all
.
的支持
来自文档的示例:
supplier_query = from s in Supplier, select: s.city
from c in Customer, select: c.city, union: ^supplier_query
背景:
我正在编写一个简单的 Q/A 网站。与 Whosebug 非常相似,在此站点中,用户可以 like/upvote 提出问题、回答或评论。
问题:
我正在努力编写一个 Ecto 查询,该查询可以 return 用户 liked/upvoted 的所有问题、答案或评论 liked/upvoted。
具体来说,我想编写一个查询:
- Returns 由特定用户作为单个列表投票的所有问题、评论和答案
- 问题、答案和评论列表按投票时间排序
这个查询似乎需要 UNION,根据我的理解,这是 not yet supported by ecto 2.0。
因此,我想知道是否有人可以向我展示或指出在 Ecto 中处理此类查询的正确方向。感谢您的任何帮助。
以下是相关模型的架构。
...
schema "users" do
...
has_many :answer_upvotes, AnswerUpvote
has_many :comment_upvotes, CommentUpvote
has_many :question_upvotes, QuestionUpvote
many_to_many :upvoted_answers, Answer, join_through: AnswerUpvote
many_to_many :upvoted_comments, Comment, join_through: CommentUpvote
many_to_many :upvoted_questions, Question, join_through: QuestionUpvote
timestamps
end
...
schema "answer_upvotes" do
belongs_to :answer, Answer
belongs_to :user, User
timestamps
end
...
schema "comment_upvotes" do
belongs_to :comment, Comment
belongs_to :user, User
timestamps
end
...
schema "question_upvotes" do
belongs_to :question, Question
belongs_to :user, User
timestamps
end
...
schema "questions" do
...
belongs_to :user, User
has_many :answers, Answer
has_many :upvotes, QuestionUpvote
many_to_many :upvoting_users, User, join_through: QuestionUpvote
timestamps
end
...
schema "answers" do
...
belongs_to :question, Question
belongs_to :user, User
has_many :comments, Comment
has_many :upvotes, AnswerUpvote
many_to_many :upvoting_users, User, join_through: AnswerUpvote
timestamps
end
...
schema "comments" do
...
belongs_to :answer, Answer
belongs_to :user, User
has_many :upvotes, CommentUpvote
many_to_many :upvoting_users, User, join_through: CommentUpvote
timestamps
end
编辑
我可以编写一个查询来按投票日期分别对问题、答案或项目进行排序。
例如:
upvoted_answers_query =
from answer in Answer,
join: upvote in assoc(answer, :upvotes), where: upvote.user_id == ^user.id,
order_by: upvote.inserted_at
select: answer
但我不确定如何编写一个单一的 Ecto 查询,无需使用联合或编写原始 SQL。
目前不支持,但有一个开放的工单:https://github.com/elixir-ecto/ecto/issues/1549
Ecto v3.0.0 (2018-10-29) 添加了对 union
和 union_all
.
来自文档的示例:
supplier_query = from s in Supplier, select: s.city
from c in Customer, select: c.city, union: ^supplier_query