无法创建用于查询嵌套父项的 Fluent ORM 查询
Unable to create a Fluent ORM query for querying nested parents
我有 3 个表,LastName、MiddleName 和 FirstName... FirstName 有 MiddleNameID 作为父项,MiddleName 有 LastName.id 作为父项
模型看起来像这样
final class LastName: Model, Content {
static let schema = "lastnames"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Children(for: \.$lastname)
var middle_names: [MiddleName]
init() { }
init(id: UUID? = nil, name: String) {
self.id = id
self.name = name
}
}
final class MiddleName: Model, Content {
static let schema = "middlenames"
@ID(key: .id)
var id: UUID?
@Parent(key: "last_name_id")
var lastname: LastName
@Field(key: "name")
var name: String
@Children(for: \.$middleNameId)
var firstNames: [FirstName]
init() { }
init(id: UUID? = nil, lastname: LastName, name: String ) {
self.id = id
self.lastname = lastname
self.name = name
}
}
final class FirstName: Model, Content {
static let schema = "firstnames"
@ID(key: .id)
var id: UUID?
@Parent(key: "middle_name_id")
var middleNameId: MiddleName
@Field(key: "name")
var name: String
init() { }
init(id: UUID? = nil, middleNameId: MiddleName, name: String) {
self.id = id
self.middleNameId = testBundleId
self.name = name
}
}
我想要这样的查询,例如给我所有姓氏 == Smith AND/OR middle == James 的名字记录...不确定如何使用 Fluent DSL 进行多重连接?或者给我所有与中间名 and/or 姓氏
匹配的名字
如果我必须写一个 SQL 查询可能看起来像这样
SELECT DISTINCT ON (ln.id, mn.id)
ln.name, mn.name, fn.*
FROM last_name ln
LEFT JOIN middle_name mn ON ln.id = mn.last_name_id
LEFT JOIN first_name fn ON fn.middle_name_id = mn.id
WHERE ( mn.name <> '' AND fn.name <> '' ) AND
(true AND ln.name ~ 'smith')
ORDER BY ln.id, mn.id, fn.id
您可以在 Fluent 查询中执行此操作,例如:
return Lastname.query(on: req)
.filter(\.$name == "Smith")
.with(\.$middle_names) { [=10=].with(\.$firstnames) }
.all()
.flatMap { wholeNames in
let result = wholeNames.filter { [=10=].middle_names.contains("James") }
// continue
}
这将为您提供中间名是 James 的所有 Smiths。您可以将其用作 OR 变体的基础。它的工作原理是首先过滤 Smith 的姓氏,然后 with
加入中间名,但闭包确保也加入名字。
我认为没有办法将中间名过滤器构建到查询中,所以我认为您必须按照我所展示的那样进行。
我有 3 个表,LastName、MiddleName 和 FirstName... FirstName 有 MiddleNameID 作为父项,MiddleName 有 LastName.id 作为父项
模型看起来像这样
final class LastName: Model, Content {
static let schema = "lastnames"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Children(for: \.$lastname)
var middle_names: [MiddleName]
init() { }
init(id: UUID? = nil, name: String) {
self.id = id
self.name = name
}
}
final class MiddleName: Model, Content {
static let schema = "middlenames"
@ID(key: .id)
var id: UUID?
@Parent(key: "last_name_id")
var lastname: LastName
@Field(key: "name")
var name: String
@Children(for: \.$middleNameId)
var firstNames: [FirstName]
init() { }
init(id: UUID? = nil, lastname: LastName, name: String ) {
self.id = id
self.lastname = lastname
self.name = name
}
}
final class FirstName: Model, Content {
static let schema = "firstnames"
@ID(key: .id)
var id: UUID?
@Parent(key: "middle_name_id")
var middleNameId: MiddleName
@Field(key: "name")
var name: String
init() { }
init(id: UUID? = nil, middleNameId: MiddleName, name: String) {
self.id = id
self.middleNameId = testBundleId
self.name = name
}
}
我想要这样的查询,例如给我所有姓氏 == Smith AND/OR middle == James 的名字记录...不确定如何使用 Fluent DSL 进行多重连接?或者给我所有与中间名 and/or 姓氏
匹配的名字如果我必须写一个 SQL 查询可能看起来像这样
SELECT DISTINCT ON (ln.id, mn.id)
ln.name, mn.name, fn.*
FROM last_name ln
LEFT JOIN middle_name mn ON ln.id = mn.last_name_id
LEFT JOIN first_name fn ON fn.middle_name_id = mn.id
WHERE ( mn.name <> '' AND fn.name <> '' ) AND
(true AND ln.name ~ 'smith')
ORDER BY ln.id, mn.id, fn.id
您可以在 Fluent 查询中执行此操作,例如:
return Lastname.query(on: req)
.filter(\.$name == "Smith")
.with(\.$middle_names) { [=10=].with(\.$firstnames) }
.all()
.flatMap { wholeNames in
let result = wholeNames.filter { [=10=].middle_names.contains("James") }
// continue
}
这将为您提供中间名是 James 的所有 Smiths。您可以将其用作 OR 变体的基础。它的工作原理是首先过滤 Smith 的姓氏,然后 with
加入中间名,但闭包确保也加入名字。
我认为没有办法将中间名过滤器构建到查询中,所以我认为您必须按照我所展示的那样进行。