GORM 中查询关联的子查询

Subqueries for querying associations in GORM

我在 GORM 中有以下域。

class Topic {
static hasMany = [resources: Resource, subscriptions: Subscription]
}

class Resource {
static belongsTo = [resourceOf: Topic]
}

class Subscription {
 static belongsTo = [subscriptionOf: Topic]
}

我无法使用 criterias/named 子查询找到 运行 子查询的语法。例如,如何使用条件在 GORM 中编写以下查询。

select topic.id, 
(select count(*) from Resource where resourceOf.id = topic.id) as numRes,
(select count(*) from Subscription where subscriptionOf.id = topic.id) as numSubs
from topic
where topic.id in (<My topic ids>)
group by topic.id;

这是非常基本的东西,但我找不到相同的文档。

有谁知道如何使用 GORM 中的 namedQueries 完成此操作?

我的grails版本是2.4.4

您面临的问题是 namedQueries 不应该与预测(摘要)一起使用。退后一步,重新设定您对使用 namedQueries.

时可以和 应该 做什么的期望

命名查询是创建标识较大集合的子集的查询的便捷方式。将其视为逐步过滤数据。如果您查看文档中的示例,您将看到正在对此进行演示。这使得 namedQueries 非常强大,但在特定的用例中。

来自 documentation 的示例:

// get all old publications with more than 350 pages
// and the word 'Grails' in the title
def pubs = Publication.oldPublicationsLargerThan(350).findAllByTitleLike('%Grails%')

另一个例子可能是:

def divisions = Division.locatedIn('Sweden').havingNoOustandingBalance().havingMoreThanXEmployees(50).currentlyOpen().notOnFire()

在其他用例中,例如使用摘要和预测,它们是不够的。不是因为它们设计不佳或无能,而是因为这不是它们的设计目的。

预测和总结确实应该通过 createCriteriaHQL 本身来创建。

虽然您可以破解 namedQueries 来进行预测和总结,但您会与框架作斗争。将正确的工具用于正确的工作,并完成更多工作。

已更新 然而,综上所述,这个 blog post 解释了如何将投影与命名查询(和条件)一起使用。它应该能让您更好地了解投影在 GORM 中的工作原理。

您的查询是"give me the topics matching a given list of topics and their respective number of resources and subscriptions."

(编辑以反映评论) 我认为这可能对你有用:

def myTopicIds = ['1', '2']  // search for ids 1 and 2
def criteria = Topic.createCriteria()
def results = criteria.list() {
    'in'('id', myTopicIds)  // restrict results to only those matching your given ids
    projections {
        property("id")
        resources {
            countDistinct('id')   
        }
        subscriptions {
            countDistinct('id')   
        }
       groupProperty('id')
    }
}.collect {
        [
            topicId: it[0],
            numRes: it[1],
            numSubs: it[2]
        ]
    }

collect 更改了结果集合并允许您将结果作为地图引用,其中每个项目都有 3 个键并显示名称,否则您将只能引用无名数组项目。

你为什么不试试这样的东西...

def exampleSubQuery = new grails.gorm.DetachedCriteria(Resource).build {
   // your criteria here, "normal" GORM
   // and the same for Subscription 
}

...然后将此子查询附加到您的主查询中。

看看这个,可能会对你有所帮助:Can't get "count" and "groupBy" with Grails DetachedCriteria