我正在尝试编写返回以下内容的 HQL 查询:
他们的propertyTags 在我的inclusionTags 中
或者我的propertyTags 在他们的inclusionTags 中,
并且他们的propertyTags 不在我的exclusionTags 中,
并且我的propertyTags 不在他们的exclusionTags 中。
这是我到目前为止所得到的:
def thePropertyTags = this.propertyTags
if(thePropertyTags == null || thePropertyTags.size() == 0) {
thePropertyTags = [ Tag.UNUSED_TAG ]
}
def theInclusions = this.inclusionTags
if(theInclusions == null || theInclusions.size() == 0) {
theInclusions = [ Tag.UNUSED_TAG ]
}
def theExclusions = this.exclusionTags
if(theExclusions == null || theExclusions.size() == 0) {
theExclusions = [ Tag.UNUSED_TAG ]
}
List<MyDomain> objects = MyDomain.executeQuery("""
SELECT DISTINCT o
FROM MyDomain o
JOIN o.propertyTags as propertyTags
JOIN o.exclusionTags as exclusions
JOIN o.inclusionTags as inclusions
WHERE o.id != :id
AND o.isActive = true
AND (
exclusions IS NULL
OR exclusions IS EMPTY
OR exclusions NOT in (:propertyTags)
)
AND propertyTags NOT in (:exclusions)
AND (
inclusions in (:propertyTags)
OR propertyTags in (:inclusions)
)
""", [id: id, inclusions: theInclusions, exclusions: theExclusions, propertyTags: thePropertyTags])
问题是无论包含/属性标签匹配,加入 excludeTags 不会返回任何内容。删除所有排除子句仍然不返回任何内容,要返回任何内容的唯一方法是完全删除 JOIN。
领域:
MyDomain {
boolean isActive = true
static hasMany = [propertyTags: Tag, inclusionTags: Tag, exclusionTags: Tag]
static constraints = {
propertyTags(nullable: false)
inclusionTags(nullable: false)
exclusionTags(nullable: false)
}
}
Tag {
private static final List<Integer> TAG_TYPES = [...]
String name
int type
String description
static constraints = {
name(unique: true, nullable: false, blank: false)
type(inList: [TAG_TYPES])
description(nullable: true, blank: true)
}
}
更新:
我已将包含/排除更改为LEFT JOIN
类似的,但如果排除在查询中,仍然没有返回记录:
List<MyDomain> objects = MyDomain.executeQuery("""
SELECT DISTINCT o
FROM MyDomain o
JOIN o.propertyTags as propertyTags
LEFT JOIN o.exclusionTags as exclusions
LEFT JOIN o.inclusionTags as inclusions
WHERE o.id != :id
AND o.isActive = true
AND exclusions NOT in (:propertyTags)
AND propertyTags NOT in (:exclusions)
AND (
inclusions in (:propertyTags)
OR propertyTags in (:inclusions)
)
""", [id: id, inclusions: theInclusions, exclusions: theExclusions, propertyTags: thePropertyTags])