简体   繁体   中英

Composite Hibernate query with subquery using groupProperty and count

I am stuck with my Hibernate query and asking for some help :) In my scenario, there is table with server logs, where different actions done by users are logged.

CREATE TABLE log (
    id VARCHAR(12) NOT NULL ,
    type INT(2) NOT NULL ,
    userId VARCHAR(12) NULL ,
    articleId VARCHAR(12) NULL ,
    date DATETIME NOT NULL ,
    ip VARCHAR(40) NULL ,
    description VARCHAR(999) NULL ,
    PRIMARY KEY (id) )
DEFAULT CHARACTER SET = utf8 COLLATE = utf8_general_ci;

When user reads some article, the log with his ip address, his userId and the articleId is write down into databse. The objective I am trying to reach is to get Article , which was opened by certain user the most time.

UserId and type are known when query is processing. I was able to create code something like this, but I know it cannot work.

DetachedCriteria subquery = DetachedCriteria.forClass(Log.class)
                .add(Restrictions.eq("userId", uId))
                .add(Restrictions.eq("type", type))
                .setProjection(Projections.projectionList()
                    .add(Projections.groupProperty("articleId")));
Article art = (Article) session.createCriteria(Article.class)
                .add(Subqueries.propertyIn("articleId", subquery))
                .uniqueResult();

I have to add another projection to get articleId with max count of occurrences in Log table, but I dont know how. Can somebody give me a little hint ?

Thanks a lot, Ondrej :)

EDIT : Thanks to my friend and this thread Hibernate Criteria Order By , I've found solution. Maybe it's not the best and cleanest way and if you have better ideas, please, write it here. But for now, it's working solution :)

Object[] o = (Object[])session.createCriteria(Log.class)
                .add(Restrictions.eq("userId", uId))
                .add(Restrictions.eq("userId", Log.TYPE_ARTICLE_READ))
                .setProjection(Projections.projectionList()
                    .add(Projections.groupProperty("articleId"))
                    .add(Projections.count("LogId"), "count"))
                .addOrder(Order.desc("count"))
                .setMaxResults(1)
                .uniqueResult();
session.clear();
art = (Article) session.createCriteria(Article.class)
                .add(Restrictions.eq("articleId", o[0]))
                .uniqueResult(); 

In object array o[] is articleId on index 0 and count of occurrences on index 1.

Ondrej

the idea is to use the count to order it

DetachedCriteria subquery = DetachedCriteria.forClass(Log.class)
    .add(Restrictions.eq("userId", uId))
    .add(Restrictions.eq("type", type))
    .addOrder(Order.desc(Projections.rowCount()))
    .setProjection(Projections.groupProperty("articleId"))
    .setMaxResults(1);

Article art = (Article) session.createCriteria(Article.class)
    .add(Subqueries.propertyEq("articleId", subquery))
    .uniqueResult();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM