Играть! структура группы модулей морфии по дате - PullRequest
0 голосов
/ 23 января 2012

Я использую Play!фреймворк, модуль morphia-mongodb, и я вижу, что в нем есть хорошие встроенные функции для групповой агрегации.К сожалению, все примеры показывают группировку / агрегирование только по фиксированному полю, тогда как мне нужно агрегировать по вычисляемому полю: отметка времени сгруппирована по дням.Мне интересно, если кто-нибудь знает правильный подход к этому?

Я знаю, что я могу просто прибегнуть к нативной карте / уменьшить (что само по себе потребовалось немного копать, чтобы выяснить, поэтому я публикую здесь для справки, используя фильмы и расписание сеансов):

        DBCollection coll = Movie.col();
        String map = "function() { " +
            (this.showtime.getMonth() + 1) + '/' + this.showtime.getDate()}; "
            + "var key = {date: this.showtime.getFullYear() + '/' 
            + (this.showtime.getMonth() + 1)       
            + '/' + this.showtime.getDate()}; "
            + "emit(key, {count: 1}); }";

        String reduce = "function(key, values) { var sum = 0; "
            + " values.forEach( function(value) {sum += value['count'];} );"
            + " return {count: sum}; }";

        String output = "dailyShowingCount";

        MapReduceOutput out = coll.mapReduce(
            map, reduce, output, MapReduceCommand.OutputType.REPLACE, null);

        SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");    
        for (Iterator<DBObject> itr = out.results().iterator(); itr.hasNext();) {
            DBObject dbo = itr.next();

            String compoundKeyStr = dbo.get("_id").toString();
            String compoundValStr = dbo.get("value").toString();

            DBObject compKey = (DBObject)JSON.parse(compoundKeyStr);
            DBObject compVal = (DBObject)JSON.parse(compoundValStr);

            //don't know why count returns as a float, but it does, so i need to convert    
            Long dCount = new Double(
               Double.parseDouble(compVal.get("count").toString())
            ).longValue();

            Date date = df.parse(compKey.get("date").toString());
        }

Но если уже есть элегантный встроенный способ выполнить эту агрегацию с модулем morphia, я бы хотел использовать это вместо этого.Одна мысль, которую я имел, состояла в том, чтобы создать виртуальное поле в моем классе Java (например, «getDay ()») и затем группировать / агрегировать этим.У кого-нибудь есть опыт с этим?

1 Ответ

0 голосов
/ 24 января 2012

Самый простой способ - создать производный столбец в вашей модели и сохранить его в базе данных.

@Entity Movie extends Model {
   public Date showTime;
   private Date showTimeDate;
   @OnUpdate
   @OnAdd
   void calcShowTimeDate() {
      Calendar c = Calendar.getInstance();
      c.setTime(showTime);
      c.set(Calendar.HOUR_OF_DAY, 0);
      c.set(Calendar.MILLISECOND, 0);
      c.set(Calendar.MINUTE, 0);
      c.set(Calendar.SECOND, 0);
      showTimeDate = c.getTime()
   }
}

Затем вы можете агрегировать по столбцу showTimeDate, следуя инструкции на http://www.playframework.org/modules/morphia-1.2.4d/statistics

...