Сгруппируйте по дням и получите данные за последние семь дней относительно часового пояса в MongoDB - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть много документов, которые выглядят так.

{
  "_id" : ObjectId("5bcf7d670a31a41b382823e2"), 
  "score" : 75
}

Мой бэкэнд-язык - Java. Я использую поле _id для фильтрации данных по дате.

У меня есть метод Java, который дает мне Object_id относительно часового пояса.

public static ObjectId getObjectId(String date, String fromTimeZone) {
  SimpleDateFormat formatterFrom = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  formatterFrom.setTimeZone(TimeZone.getTimeZone(fromTimeZone));
  return new ObjectId(Long.toHexString(formatterFrom.parse(date).getTime() / 1000L) + "0000000000000000");
}

fromTimeZone может быть чем-то вроде.

GMT+08:00
UTC
Africa/Algiers
Europe/London etc.

Теперь я хотел бы добавить несколько диаграмм на панель управления моего приложения. поэтому мне нужны данные за последние 7 дней.

{date: Nov-01, score:75}
{date: Nov-02, score:75}
{date: Nov-03, score:75}
{date: Nov-04, score:75}
{date: Nov-05, score:75}
{date: Nov-06, score:75}
{date: Nov-07, score:75}

Поскольку многие пользователи используют разные часовые пояса, я действительно понятия не имею, как это сделать.

помогите пожалуйста.

1 Ответ

0 голосов
/ 08 ноября 2018

Вам просто нужно выбрать соответствующие документы, сгруппировать по дате с часовым поясом, суммировать результаты и вывести документ.

Выборка и форматирование результатов

//Create Variables
String endDt = "2018-11-08 01:02:03";
String startDt = "2018-11-01 01:02:03";
String timeZone = "GMT+08:00";

//Query Filter
Bson query = Aggregates.match(Filters.and(
     Filters.lte("_id", getObjectId(endDt,timeZone)),
     Filters.gte("_id", getObjectId(startDt,timeZone ))
));

//Objectid to datetime expression
Document toDate = new Document("$toDate", "$_id");
Bson objectIdToDate = Aggregates.projection(Projections.fields(
     Projections.excludeId(),
     Projections.include("score"),
     Projections.computed("date", toDate)
));

//Date expression with timezone
Document dateExpression = Document.parse(
  "{'$dateFromParts':{
   'year':{'$year':{'date':'$date','timezone:'"+ timeZone +"}},
   'month':{'$month':{'date':'$date','timezone':"+ timeZone +"}},
   'day':{'$dayOfMonth':{'date':'$date','timezone':"+ timeZone +"}}
   }}"
);

//Group by Date
Bson group = Aggregates.group(new Document("$_id", dateExpression), Accumlators.sum("score", "$score"));

//final output
Bson fields = Aggregates.projection(Projections.fields(
     Projections.excludeId(),
     Projections.include("score"),
     Projections.computed("date", "$_id")
));

//Fetch matching records
AggregateIterable<Document> iterable = collection.aggregate(Arrays.asList(query,objectIdToDate,group,fields));

//Format results
for(Document document:iterable) {
    document.put("date", formatDateToMonthDay(date)); 
}

Вспомогательные методы

public static String formatDateToMonthDay(Date date) {
    DateTimeFormattter monthDayFormatter = DateTimeFormatter.ofPattern("MMM-dd");
    Instant instant = date.toInstant();
    return instant.format(monthDayFormatter); 
}

public ObjectId getObjectId(String date, String fromTimeZone) {
    DateTimeFormattter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    LocalDateTime localDateTime = LocalDateTime.parse(date,formatter);
    Instant instant = LocalDateTime.ofInstant(instant, ZoneId.of(fromTimeZone)).toInstant();
    return new ObjectId(Long.toHexString(instant.getEpochSecond()) + "0000000000000000");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...