MentionableDAO implements IMentionableDAO<K, T> { @Override public Map<String, Double> getActiveColumnsByToMV(String columnName, Interval interval, int resultSize, boolean withBots) { EntityManager entityManager = entityManagerFactory.createEntityManager(); CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Tuple> query = cb.createTupleQuery(); Root<T> from = query.from(type); ParameterExpression<DateTime> startDateParam = cb.parameter(DateTime.class); ParameterExpression<DateTime> endDateParam = cb.parameter(DateTime.class); Expression<Double> occurrences = from.get("occurrences").as(Double.class); Subquery<Long> totalQuery = query.subquery(Long.class); Root<MessageSummary> totalFrom = totalQuery.from(MessageSummary.class); totalQuery.select(cb.sum(totalFrom.get("occurrences"))); Path<DateTime> totalMentionTime = totalFrom.get("mentionTime"); Path<MessageType> messageType = totalFrom.get("value"); List<Predicate> wherePredicates = Lists.newArrayListWithCapacity(4); wherePredicates.add(cb.greaterThanOrEqualTo(totalMentionTime, startDateParam)); wherePredicates.add(cb.lessThan(totalMentionTime, endDateParam)); wherePredicates.add(cb.equal(messageType, MessageType.MESSAGE)); if (!withBots) { wherePredicates.add(cb.equal(totalFrom.get("bot"), withBots)); } totalQuery.where(wherePredicates.toArray(new Predicate[wherePredicates.size()])); Expression<Double> ratio = cb.quot(cb.sum(occurrences), totalQuery).as(Double.class); Path<String> columnPath = from.get(columnName); query.multiselect(columnPath, ratio); Path<DateTime> mentionTime = from.get("mentionTime"); wherePredicates = Lists.newArrayListWithCapacity(4); wherePredicates.add(cb.greaterThanOrEqualTo(mentionTime, startDateParam)); wherePredicates.add(cb.lessThan(mentionTime, endDateParam)); wherePredicates.add(cb.isNotNull(columnPath)); if (!withBots) { wherePredicates.add(cb.equal(from.get("bot"), withBots)); } query.where(wherePredicates.toArray(new Predicate[wherePredicates.size()])); query.groupBy(columnPath); query.orderBy(cb.desc(ratio)); try { List<Tuple> resultList = entityManager.createQuery(query) .setMaxResults(resultSize) .setParameter(startDateParam, interval.getStart()) .setParameter(endDateParam, interval.getEnd()) .getResultList(); Map<String, Double> result = Maps.newLinkedHashMap(); for (Tuple tuple : resultList) { result.put(tuple.get(columnPath), tuple.get(ratio)); } return result; } finally { closeEntityManager(entityManager); } } protected  MentionableDAO(EntityManagerFactory entityManagerFactory, Class<T> type); @Override void persistValue(T value); @Override T getValue(T value); @Override List<T> getAllMentionsForValue(K value, Interval interval,
                                          List<String> roomNames, List<String> usernames); @Override List<T> getAllMentions(Interval interval, List<String> roomNames,
                                  List<String> usernames,
                                  boolean withBots); List<T> internalGetAllMentionsForValue(Optional<K> value,
                                                  Interval interval,
                                                  List<String> roomNames,
                                                  List<String> usernames,
                                                  boolean withBots); @Override LabeledDenseMatrix<String> getRoomSimilaritiesByValue(Interval interval,
                                                                 boolean withBots); @Override LabeledDenseMatrix<String> getUserSimilaritiesByValue(Interval interval,
                                                                 boolean withBots); @Override int getTotalMentionsForType(K value, Interval interval, List<String> roomNames,
                                       List<String> usernames, boolean withBots); @Override int getTotalMentionsOfType(Interval interval,
                                      List<String> roomNames,
                                      List<String> usernames,
                                      boolean withBots); @Override Map<K, Long> getTopValuesOfType(Interval interval,
                                           List<String> roomNames,
                                           List<String> usernames,
                                           int resultSize,
                                           boolean withBots); @Override Map<String, Double> getActiveColumnsByToTV(String columnName, Interval interval,
                                                      int resultSize, boolean withBots); @Override Map<String, Double> getActiveColumnsByToMV(String columnName, Interval interval,
                                                      int resultSize, boolean withBots); @Override Class<T> getType(); @Override void close();  }
@Test public void testGetActiveColumnsByToMV() throws Exception { DateTime end = DateTime.now(); DateTime start = end.minusDays(1); Interval interval = new Interval(start, end); IMessageSummaryDAO msgSummaryDao = ChatAlyticsDAOFactory.createMessageSummaryDAO(config); msgSummaryDao.startAsync().awaitRunning(); underTest.persistValue(new EmojiEntity("u1", "r1", start.plusMillis(1), "a", 1, true)); underTest.persistValue(new EmojiEntity("u2", "r1", start.plusMillis(3), "c", 1, false)); underTest.persistValue(new EmojiEntity("u1", "r2", start.plusMillis(4), "a", 1, true)); msgSummaryDao.persistMessageSummary(new MessageSummary("u1", "r1", start.plusMillis(1), MESSAGE, 1, true)); msgSummaryDao.persistMessageSummary(new MessageSummary("u1", "r1", start.plusMillis(1), MESSAGE, 1, true)); msgSummaryDao.persistMessageSummary(new MessageSummary("u1", "r1", start.plusMillis(1), CHANNEL_JOIN, 1, true)); msgSummaryDao.persistMessageSummary(new MessageSummary("u2", "r1", start.plusMillis(1), MESSAGE, 1, false)); msgSummaryDao.persistMessageSummary(new MessageSummary("u2", "r1", start.plusMillis(1), CHANNEL_JOIN, 1, false)); msgSummaryDao.persistMessageSummary(new MessageSummary("u1", "r2", start.plusMillis(1), MESSAGE, 1, true)); msgSummaryDao.persistMessageSummary(new MessageSummary("u3", "r2", start.plusMillis(1), MESSAGE, 1, false)); msgSummaryDao.persistMessageSummary(new MessageSummary("u1", "r2", start.plusMillis(1), MESSAGE_CHANGED, 1, true)); Map<String, Double> result = underTest.getActiveColumnsByToMV("username", interval, 100, true); assertEquals(2, result.size()); assertEquals(0.4, result.get("u1").doubleValue(), 0); assertEquals(0.2, result.get("u2").doubleValue(), 0); double previousValue = Double.MIN_VALUE; for (double value : result.values()) { assertTrue(Double.compare(value, previousValue) > 0); } result = underTest.getActiveColumnsByToMV("username", interval, 100, false); assertEquals(1, result.size()); assertEquals(0.5, result.get("u2").doubleValue(), 0); interval = new Interval(start.plusMillis(2), start.plusMillis(6)); result = underTest.getActiveColumnsByToTV("username", interval, 100, true); assertEquals(2, result.size()); assertEquals(0.5, result.get("u1").doubleValue(), 0); assertEquals(0.5, result.get("u2").doubleValue(), 0); previousValue = Double.MIN_VALUE; for (double value : result.values()) { assertTrue(Double.compare(value, previousValue) > 0); } msgSummaryDao.stopAsync().awaitTerminated(); }