代码之家  ›  专栏  ›  技术社区  ›  Langali

在grails中使用的常规方法

  •  0
  • Langali  · 技术社区  · 16 年前
    Article { 
       String categoryName 
       static hasMany = [ 
            tags: Tag 
        ] 
    } 
    
    Tag { 
       String name 
    }
    

    现在我想找到所有相关文章的列表。相关含义,与myarticle具有相同类别名称或与myartcle具有相同标记的所有文章。

    只有匹配的categoryname,下面是如何使用闭包获取related文章的。

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

    有人想尝试通过categoryname或tag name(以groovy的方式)查找所有文章吗?

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

    3 回复  |  直到 15 年前
        1
  •  1
  •   Dónal    16 年前

    这将起作用:

    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() )

        2
  •  0
  •   jabley    15 年前

    我认为您需要对每个文章标记使用单独的查询:

    // 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
    

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

        3
  •  -1
  •   Jean Barmash    16 年前

    理想情况下,您应该使用criteria query,bug,因为您说过您不关心性能,应该这样做:

    def category = 
    def tagName
    
    def relatedArticles = Article.list().findAll {
        (it.categoryName == myArticle.categoryName) || ( it.tags.contains(tagName) )            
    } 
    
    推荐文章