[英]Querying nested children in Vapor's Fluent
環境:蒸汽/流利的 4.0.0
我有一個帶有 model 的樹狀結構數據,如下所示:
final class Ingredient: Model {
static let schema = "ingredients"
@ID(key: "id")
var id: UUID?
@Field(key: "name")
var name: String
@OptionalParent(key: "parent_id")
var parent: Ingredient?
@Children(for: \.$parent)
var children: [Ingredient]
}
我想在 API 方法之一中將整個樹作為 JSON 返回。
func index(req: Request) throws -> EventLoopFuture<[APIIngredient]> {
// Gathering top-level nodes without parents
let ingredients = try Ingredient.query(on: req.db)
.filter(\.$parent.$id == nil)
.sort(\.$name)
.all()
.wait()
enter code here
// Creating API models
let apiIngredients = try ingredients.map {
try APIIngredient(
ingredient: $0,
childrenGetter: {
try $0.$children.query(on: req.db).all().wait()
}
)
}
return req.eventLoop.future(apiIngredients)
}
但我發現 .wait() 不允許在請求處理程序中使用。 解決這個問題的正確方法是什么?
wait()
是不允許的,因為它阻塞了 EventLoop。 所以你有幾個選擇:
按照尼克的建議使用急切加載。 這將更有效率,因為它只有 2 個 DB 查詢而不是 N+1。
使用 async/await 來寫你想要的
妥善處理期貨。 而不是使用wait()
開關來處理期貨:
func index(req: Request) throws -> EventLoopFuture<[APIIngredient]> {
// Gathering top-level nodes without parents
return Ingredient.query(on: req.db)
.filter(\.$parent.$id == nil)
.sort(\.$name)
.all()
.flatMap { ingredients in
ingredients.map { ingredient -> EventLoopFuture<APIIngredient>
let future = ingredient.$children.query(on: req.db).all().map { children in
APIIngredient(ingredient: ingredient, children: children)
}
}.flatten(on: req.eventLoop)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.