Vapor 3 和 Fluent - 嵌套查询
Vapor 3 and Fluent - nested query
我正在尝试在 Vapor 3 和 Fluent 中进行嵌套查询。关键是我需要从具有特定 eventID 的每个团队中获取所有用户。团队是 children 个活动。用户是 children 个团队。在此先感谢您的帮助。
每个活动只有 15 个团队,但每个团队有 12 个用户
事件模型如下:
final class Event: Codable {
var id: Int?
var name: String
}
extension Event {
var teams: Children<Event, Team> {
return children(\.eventID)
}
}
这是团队模型
final class Team: Codable {
var id: Int?
var name: String
var icon: String
var eventID: Event.ID
}
extension Team {
var user: Parent<Team, Event> {
return parent(\.eventID)
}
}
extension Team {
var users: Children<Team, User> {
return children(\.teamID)
}
}
这是用户模型。
final class User: Codable {
var id: UUID?
var name: String
var email: String
var eventID: Event.ID
var teamID: Team.ID
}
extension User {
var user: Parent<User, Team> {
return parent(\.teamID)
}
}
我需要发送事件 ID,我希望它发送给 return 所有团队中的所有用户
func getUsersForEvent(_ req: Request) throws -> Future<[User]> {
return try req.parameters.next(Event.self).flatMap(to: [User].self) { event in
return try event.teams.query(on: req).all().flatMap(to: [User].self) { team in
return try team.users.query(on: req).all()
}
}
}
您可以使用原始 SQL 查询或使用 SwifQL lib
轻松查询
这里有一个 SwifQL 的例子
struct TeamWithUsers: Content {
let id: UUID
let name, icon: String
let users: [User]
}
func getCategoriesWithProducts(_ req: Request) throws -> Future<[TeamWithUsers]> {
return try req.parameters.next(Event.self).flatMap { event in
let usersSubquery = SwifQL
.select(Fn.coalesce(Fn.array_agg(Fn.to_jsonb(User.table)), PgArray() => .jsonbArray))
.from(User.table)
.where(\User.teamID == \Team.id)
let query = try SwifQL
.select(\Team.id, \Team.name, \Team.icon, |usersSubquery | => "users")
.from(Team.table)
.where(\Team.eventID == event.requireID())
// here you could print the raw query for debugging
// print(query.prepare(.psql).plain)
return query.execute(on: req, as: .psql).all(decoding: TeamWithUsers.self)
}
}
这是我在 Ray Wenderlich 的书的帮助下得出的结论。在我的任务中,我不需要 return 所有用户,一次只需要查看 1 个事件的团队,因此我将 eventID 作为参数传入。
关于如何按 teamScore 对结果进行排序的任何指导?
func getTeamsWithUsersForEvent(_ req: Request) throws -> Future<[TeamWithUsers]> {
let currentID = try req.parameters.next(Int.self)
print("currentID \(currentID)")
return Team.query(on: req).filter(\Team.eventID == currentID).all().flatMap(to: [TeamWithUsers].self) { team in
try team.map { team in
try team.users.query(on: req).all().map { users in
TeamWithUsers(
id: team.id,
name: team.name,
icon: team.icon,
eventID: team.eventID,
//rawScore: team.rawScore,
//users: users,
count: users.count,
teamScore: team.rawScore / users.count
)
}
}.flatten(on: req)
}
}
struct TeamWithUsers: Content {
let id: Int?
let name: String
let icon: String
let eventID: Event.ID
//let rawScore: Int
//let users: [User]
let count: Int
let teamScore: Int
}
我正在尝试在 Vapor 3 和 Fluent 中进行嵌套查询。关键是我需要从具有特定 eventID 的每个团队中获取所有用户。团队是 children 个活动。用户是 children 个团队。在此先感谢您的帮助。 每个活动只有 15 个团队,但每个团队有 12 个用户
事件模型如下:
final class Event: Codable {
var id: Int?
var name: String
}
extension Event {
var teams: Children<Event, Team> {
return children(\.eventID)
}
}
这是团队模型
final class Team: Codable {
var id: Int?
var name: String
var icon: String
var eventID: Event.ID
}
extension Team {
var user: Parent<Team, Event> {
return parent(\.eventID)
}
}
extension Team {
var users: Children<Team, User> {
return children(\.teamID)
}
}
这是用户模型。
final class User: Codable {
var id: UUID?
var name: String
var email: String
var eventID: Event.ID
var teamID: Team.ID
}
extension User {
var user: Parent<User, Team> {
return parent(\.teamID)
}
}
我需要发送事件 ID,我希望它发送给 return 所有团队中的所有用户
func getUsersForEvent(_ req: Request) throws -> Future<[User]> {
return try req.parameters.next(Event.self).flatMap(to: [User].self) { event in
return try event.teams.query(on: req).all().flatMap(to: [User].self) { team in
return try team.users.query(on: req).all()
}
}
}
您可以使用原始 SQL 查询或使用 SwifQL lib
轻松查询这里有一个 SwifQL 的例子
struct TeamWithUsers: Content {
let id: UUID
let name, icon: String
let users: [User]
}
func getCategoriesWithProducts(_ req: Request) throws -> Future<[TeamWithUsers]> {
return try req.parameters.next(Event.self).flatMap { event in
let usersSubquery = SwifQL
.select(Fn.coalesce(Fn.array_agg(Fn.to_jsonb(User.table)), PgArray() => .jsonbArray))
.from(User.table)
.where(\User.teamID == \Team.id)
let query = try SwifQL
.select(\Team.id, \Team.name, \Team.icon, |usersSubquery | => "users")
.from(Team.table)
.where(\Team.eventID == event.requireID())
// here you could print the raw query for debugging
// print(query.prepare(.psql).plain)
return query.execute(on: req, as: .psql).all(decoding: TeamWithUsers.self)
}
}
这是我在 Ray Wenderlich 的书的帮助下得出的结论。在我的任务中,我不需要 return 所有用户,一次只需要查看 1 个事件的团队,因此我将 eventID 作为参数传入。
关于如何按 teamScore 对结果进行排序的任何指导?
func getTeamsWithUsersForEvent(_ req: Request) throws -> Future<[TeamWithUsers]> {
let currentID = try req.parameters.next(Int.self)
print("currentID \(currentID)")
return Team.query(on: req).filter(\Team.eventID == currentID).all().flatMap(to: [TeamWithUsers].self) { team in
try team.map { team in
try team.users.query(on: req).all().map { users in
TeamWithUsers(
id: team.id,
name: team.name,
icon: team.icon,
eventID: team.eventID,
//rawScore: team.rawScore,
//users: users,
count: users.count,
teamScore: team.rawScore / users.count
)
}
}.flatten(on: req)
}
}
struct TeamWithUsers: Content {
let id: Int?
let name: String
let icon: String
let eventID: Event.ID
//let rawScore: Int
//let users: [User]
let count: Int
let teamScore: Int
}