2010-01-06 29 views
0
Article { 
    String categoryName 
    static hasMany = [ 
     tags: Tag 
    ] 
} 

Tag { 
    String name 
} 

现在我想查找所有相关文章的列表。相关含义,与myArticle具有相同类别名称的所有文章或与myArtcle具有相同标签的所有文章。Groovy在Grails中的做法

只有匹配的categoryName,这里是我将如何使用闭包获取relatedArticles。

def relatedArticles = Article.list().find {it.categoryName == myArticle.categoryName } 

任何人都希望通过CategoryName或Tag Name(以常规方式)查找所有文章?

任何使用Criteria或自定义查询的解决方案也是值得赞赏的。

回答

1

这会工作:

def myArticle = // the article you want to match 

def relatedArticles = Article.list().findAll { 
    (it.categoryName == myArticle.categoryName || 
      it.tags.name.intersect(myArticle.tags.name)) && 
      it.id != myArticle.id)    
} 

但是,如果你有一个相当大的数量的物品,只有在预期当中的少数与之相匹配的是效率极其低下的,因为这将加载所有的文章,然后遍历它们都在寻找匹配。

一种更好的方式是简单地写,只有负载匹配的文章(而不是调用Article.list()

+0

就性能问题达成一致。我只有大约50篇文章,它不会增加太多。 – Langali 2010-01-06 20:12:53

+0

该代码最初是为了匹配类别AND标签而编写的,我重新阅读了该问题并更改了代码,以便与类别OR标签匹配 – 2010-01-06 20:43:06

+0

您现在正在对字符串调用intersect()方法? – Langali 2010-01-06 20:47:52

-1

理想的查询时,你会使用条件查询,错误既然你说你不关心性能,东西像这应该工作:

def category = 
def tagName 

def relatedArticles = Article.list().findAll { 
    (it.categoryName == myArticle.categoryName) || (it.tags.contains(tagName))    
} 
+0

一篇文章有​​多个标签。那么如何包含多个标签的工作呢? – Langali 2010-01-06 20:30:27

+0

另外,我对使用标准的解决方案感兴趣。要试试吗? – Langali 2010-01-06 20:31:51

+0

您的问题,正如所述的要求“通过CategoryName或Tag Name查找所有文章”。 – 2010-01-07 01:19:49

0

我认为你需要使用每篇文章标签一个单独的查询:

// Use a LinkedHashSet to retain the result order if that is important 
def results = new LinkedHashSet() 

results.addAll(Article.findAll("from Article as article \ 
    where article.categoryName = :categoryName \ 
    and article.id != :id", 
    [ 
    categoryName:myArticle.categoryName, 
    id:myArticle.id, 
    ]) 

myArticle.tags.each { 
results.addAll(Article.executeQuery(
    "select distinct article from Article as article, \ 
    Tag as tag \ 
    where tag.name = :tag \ 
    and tag in elements(article.tags) \ 
    and article.id != :id", 
    [ 
    tag:it.name, 
    id:myArticle.id, 
    ])) 
} 

def relatedArticles = results as List 

这当你在系统中有很多内容并且希望避免为单个页面请求加载整个数据库时显然是值得的。其他改进包括为查询指定最大和偏移量参数。