2016-03-23 11 views
0

のは、私は、次の2つのクラスがあるとしましょう:NamedQuery

@Entity 
class Article { 

    @Id 
    int id; 

    @ManyToMany(mappedBy="articles") 
    List<Tag> tags; 
} 

@Entity 
@NamedQueries({ 
    @NamedQuery(name = "Tag.trends", query = "SELECT t FROM Tag t") // Some magic stuff here.. 
}) 
class Tag { 

    @Id 
    String name; 

    @ManyToMany 
    List<Articles> articles; 
} 

今、私が最もよく使われるタグを選択するために名前付きクエリを作成したいです。

これは、に参加とによって順序が必要になります。しかし、私はこれを理解していないようです。

質問: よく使われるタグを選択するにはどうすればよいですか?例えば

、以下の記事は、次のタグを持っている場合:

Article: Tags 
0: A, B 
1: A 
2: C 
3: A, C 

出力

A // 3 times 
C // 2 times 
B // 1 time 
+0

すべてのタグをグループ化し、カウントと注文降順を取得しますか? –

+0

@Nicholas私はそれらをグループ化したいとは思っていません。私はそれらを記事クラスインスタンス内の出現回数で降順に並べ替えるようにしたいと思います。 – Tim

+0

おそらくどこかに参加テーブルがあるかもしれません。なぜなら、MNを持たない人は少し無意味かもしれないからです。 –

答えて

2

:そしてもちろん、あなたがしたい場合は、カウントを無視することができます

List<Tag> t = em.createQuery("select t from Article a join a.tags t group by (t.name) order by count(t.name) desc", Tag.class).getResultList(); 
t.stream().forEach((tag)-> { 
    System.out.println("Tag = " + tag.getName()); 
}); 

をし、次のような出力を得ます記事数で注文したタグのリストを表示します。

+1

'asc'の代わりに' desc'を使い、 '.setMaxResults()'を最も人気のあるタグを最初に表示させる –

+0

@SashaSalauyouそれです。 :) – Desorder

1

は、この種の問題に後方あなたのように動作します。 SQLクエリを開始します。

select 
    count(t.name), t.name 
from article a 
    join article_tags ats 
    join tag t 
where 
    a.id=ats.article_id 
    and ats.tag_id = t.id 
group by 
    t.name 
order by 
    count(t.name) 
desc; 

ことからその後JPQLがすべき多かれ少なかれフォロー:

Hibernate: select tag2_.name as col_0_0_, count(tag2_.name) as col_1_0_ from Article article0_ inner join Tag_Article tags1_ on article0_.id=tags1_.articles_id inner join Tag tag2_ on tags1_.tags_id=tag2_.id group by tag2_.name order by count(tag2_.name) desc 
Count of A = 2 
Count of B = 1 
Count of C = 1 

UPDATE:

List<Tuple> t = em.createQuery("select t.name as name, count(t.name) as count from Article a join a.tags t group by (t.name) order by count(t.name) desc", Tuple.class).getResultList(); 
t.stream().forEach((tp)-> { 
    System.out.println("Count of " + tp.get("name") + " = " + tp.get("count")); 
}); 

これは私に次のような出力を提供しますあなたがしたい場合タグのリストは、タプルの最初の要素をタグに変更するだけです。あなたは

SELECT t FROM Tag t ORDER BY SIZE(t.articles) ASC 

のようなその何かを使用して欲しいものを達成することができます

Hibernate: select tag2_.id as id1_1_, tag2_.name as name2_1_ from Article article0_ inner join Tag_Article tags1_ on article0_.id=tags1_.articles_id inner join Tag tag2_ on tags1_.tags_id=tag2_.id group by tag2_.name order by count(tag2_.name) desc 
Tag = A 
Tag = B 
Tag = C 
+0

素晴らしいですが、これを効率的にタグのリストに表示するにはどうすればよいですか? – Tim

+0

しかし、私はすべてのタグを名前で照会する必要があり、それは非効率的です。 – Tim

+0

はい、出力が少し混乱します。 'List 'を取得したいと思います。私は本当に発生の数に気にしない、それだけで並べ替える必要があります。私は思いがけないように聞こえたくはありませんが、よりパフォーマンスの高いものにしたいと思います。すべてのタグを名前で再度照会することはできません(Id)。私はあなたがそれをこのように変更できることを願っています! – Tim

関連する問題