Временные ряды #59

Merged
romanov73 merged 10 commits from influx into master 2022-10-06 16:09:37 +04:00
5 changed files with 186 additions and 3 deletions
Showing only changes of commit 4f8d25e56e - Show all commits

View File

@ -61,6 +61,7 @@ dependencies {
implementation group: 'commons-io', name: 'commons-io', version: '2.6' implementation group: 'commons-io', name: 'commons-io', version: '2.6'
implementation group: 'net.sourceforge.htmlunit', name: 'htmlunit', version: '2.35.0' implementation group: 'net.sourceforge.htmlunit', name: 'htmlunit', version: '2.35.0'
implementation group: 'com.github.javaparser', name: 'javaparser-core', version: '3.20.2' implementation group: 'com.github.javaparser', name: 'javaparser-core', version: '3.20.2'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0' implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'

View File

@ -3,7 +3,11 @@ package ru.ulstu.extractor.model;
import org.hibernate.annotations.Fetch; import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.FetchMode;
import javax.persistence.*; import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -15,11 +19,18 @@ public class TimeSeries extends BaseEntity {
@Fetch(FetchMode.SUBSELECT) @Fetch(FetchMode.SUBSELECT)
private List<TimeSeriesValue> values = new ArrayList<>(); private List<TimeSeriesValue> values = new ArrayList<>();
public TimeSeries() {
}
public TimeSeries(String name) { public TimeSeries(String name) {
this.name = name; this.name = name;
} }
public TimeSeries(String name, List<TimeSeriesValue> values) {
this.name = name;
this.values = values;
}
public String getName() { public String getName() {
return name; return name;
} }

View File

@ -12,6 +12,15 @@ public class TimeSeriesValue extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
private TimeSeries timeSeries; private TimeSeries timeSeries;
public TimeSeriesValue() {
}
public TimeSeriesValue(Date date, Integer value) {
this.timeSeries = timeSeries;
this.date = date;
this.value = value;
}
public TimeSeriesValue(TimeSeries timeSeries, Date date, Integer value) { public TimeSeriesValue(TimeSeries timeSeries, Date date, Integer value) {
this.timeSeries = timeSeries; this.timeSeries = timeSeries;
this.date = date; this.date = date;
@ -34,11 +43,11 @@ public class TimeSeriesValue extends BaseEntity {
this.value = value; this.value = value;
} }
public TimeSeries getTimeSeriesType() { public TimeSeries getTimeSeries() {
return timeSeries; return timeSeries;
} }
public void setTimeSeriesType(TimeSeries timeSeries) { public void setTimeSeries(TimeSeries timeSeries) {
this.timeSeries = timeSeries; this.timeSeries = timeSeries;
} }
} }

View File

@ -0,0 +1,59 @@
package ru.ulstu.extractor.ts;
import org.apache.commons.lang3.time.DateUtils;
import ru.ulstu.extractor.model.TimeSeries;
import ru.ulstu.extractor.model.TimeSeriesValue;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Класс для регулировки дискретности временного ряда.
* Можно создать временной ряд с точками с секундными отметками, затем суммировать значения,
* применив одно из значений TimeSeriesInterval
*/
public class TimeSeriesDateMapper {
public TimeSeries mapTimeSeriesToInterval(TimeSeriesInterval timeSeriesInterval, TimeSeries timeSeries) {
List<TimeSeriesValue> trimmedTimeSeriesValues = timeSeries.getValues()
.stream()
.map(timeSeriesValue -> new TimeSeriesValue(trimTo(timeSeriesInterval, timeSeriesValue.getDate()),
timeSeriesValue.getValue()))
.collect(Collectors.toList());
Map<Date, Integer> groupedTimeSeriesValues = trimmedTimeSeriesValues
.stream()
.collect(Collectors.groupingBy(TimeSeriesValue::getDate,
Collectors.summingInt(TimeSeriesValue::getValue)));
return new TimeSeries(timeSeries.getName(), groupedTimeSeriesValues.entrySet()
.stream()
.map(e -> new TimeSeriesValue(e.getKey(), e.getValue()))
.collect(Collectors.toList()));
}
private Date trimTo(TimeSeriesInterval timeSeriesInterval, Date date) {
return DateUtils.truncate(date, timeSeriesInterval.calendarField);
}
/**
* Интервальность временного ряда при преобразовании
*/
public enum TimeSeriesInterval {
SECOND(Calendar.SECOND),
MINUTE(Calendar.MINUTE),
HOUR(Calendar.HOUR_OF_DAY),
DAY(Calendar.DAY_OF_MONTH),
WEEK(Calendar.WEEK_OF_MONTH),
MONTH(Calendar.MONTH),
YEAR(Calendar.YEAR);
private final int calendarField;
TimeSeriesInterval(int calendarField) {
this.calendarField = calendarField;
}
}
}

View File

@ -0,0 +1,103 @@
package ru.ulstu;
import org.junit.Assert;
import org.junit.Test;
import ru.ulstu.extractor.model.TimeSeries;
import ru.ulstu.extractor.model.TimeSeriesValue;
import ru.ulstu.extractor.ts.TimeSeriesDateMapper;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class TimeSeriesMapperTest {
@Test
public void testMappingByDay() {
Calendar c1 = GregorianCalendar.getInstance();
c1.set(2020, 5, 1, 1, 1, 1);
Calendar c2 = GregorianCalendar.getInstance();
c2.set(2020, 5, 2, 2, 1, 1);
TimeSeries timeSeries = new TimeSeries("Тестовый",
Arrays.asList(new TimeSeriesValue(c1.getTime(), 10),
new TimeSeriesValue(c2.getTime(), 10)));
TimeSeriesDateMapper mapper = new TimeSeriesDateMapper();
timeSeries = mapper.mapTimeSeriesToInterval(TimeSeriesDateMapper.TimeSeriesInterval.MONTH, timeSeries);
Assert.assertEquals(1, timeSeries.getValues().size());
Assert.assertEquals(Integer.valueOf(20), timeSeries.getValues().get(0).getValue());
}
@Test
public void testMappingByDayDifferent() {
Calendar c1 = GregorianCalendar.getInstance();
c1.set(2020, 5, 1, 1, 1, 1);
Calendar c2 = GregorianCalendar.getInstance();
c2.set(2020, 5, 2, 1, 1, 1);
TimeSeries timeSeries = new TimeSeries("Тестовый",
Arrays.asList(new TimeSeriesValue(c1.getTime(), 10),
new TimeSeriesValue(c2.getTime(), 10)));
TimeSeriesDateMapper mapper = new TimeSeriesDateMapper();
timeSeries = mapper.mapTimeSeriesToInterval(TimeSeriesDateMapper.TimeSeriesInterval.MONTH, timeSeries);
Assert.assertEquals(1, timeSeries.getValues().size());
Assert.assertEquals(Integer.valueOf(20), timeSeries.getValues().get(0).getValue());
}
@Test
public void testMappingByMonth() {
Calendar c1 = GregorianCalendar.getInstance();
c1.set(2020, 5, 1, 1, 1, 1);
Calendar c2 = GregorianCalendar.getInstance();
c2.set(2020, 5, 2, 1, 1, 1);
TimeSeries timeSeries = new TimeSeries("Тестовый",
Arrays.asList(new TimeSeriesValue(c1.getTime(), 10),
new TimeSeriesValue(c2.getTime(), 10)));
TimeSeriesDateMapper mapper = new TimeSeriesDateMapper();
timeSeries = mapper.mapTimeSeriesToInterval(TimeSeriesDateMapper.TimeSeriesInterval.MONTH, timeSeries);
Assert.assertEquals(1, timeSeries.getValues().size());
Assert.assertEquals(Integer.valueOf(20), timeSeries.getValues().get(0).getValue());
}
@Test
public void testMappingByMonthDifferent() {
Calendar c1 = GregorianCalendar.getInstance();
c1.set(2020, 5, 1, 1, 1, 1);
Calendar c2 = GregorianCalendar.getInstance();
c2.set(2020, 6, 2, 1, 1, 1);
TimeSeries timeSeries = new TimeSeries("Тестовый",
Arrays.asList(new TimeSeriesValue(c1.getTime(), 10),
new TimeSeriesValue(c2.getTime(), 10)));
TimeSeriesDateMapper mapper = new TimeSeriesDateMapper();
timeSeries = mapper.mapTimeSeriesToInterval(TimeSeriesDateMapper.TimeSeriesInterval.MONTH, timeSeries);
Assert.assertEquals(2, timeSeries.getValues().size());
Assert.assertEquals(Integer.valueOf(10), timeSeries.getValues().get(0).getValue());
}
@Test
public void testMappingByYear() {
Calendar c1 = GregorianCalendar.getInstance();
c1.set(2020, 5, 1, 1, 1, 1);
Calendar c2 = GregorianCalendar.getInstance();
c2.set(2020, 5, 2, 1, 1, 1);
TimeSeries timeSeries = new TimeSeries("Тестовый",
Arrays.asList(new TimeSeriesValue(c1.getTime(), 10),
new TimeSeriesValue(c2.getTime(), 10)));
TimeSeriesDateMapper mapper = new TimeSeriesDateMapper();
timeSeries = mapper.mapTimeSeriesToInterval(TimeSeriesDateMapper.TimeSeriesInterval.YEAR, timeSeries);
Assert.assertEquals(1, timeSeries.getValues().size());
Assert.assertEquals(Integer.valueOf(20), timeSeries.getValues().get(0).getValue());
}
@Test
public void testMappingByYearDifferent() {
Calendar c1 = GregorianCalendar.getInstance();
c1.set(2020, 5, 1, 1, 1, 1);
Calendar c2 = GregorianCalendar.getInstance();
c2.set(2021, 5, 2, 1, 1, 1);
TimeSeries timeSeries = new TimeSeries("Тестовый",
Arrays.asList(new TimeSeriesValue(c1.getTime(), 10),
new TimeSeriesValue(c2.getTime(), 10)));
TimeSeriesDateMapper mapper = new TimeSeriesDateMapper();
timeSeries = mapper.mapTimeSeriesToInterval(TimeSeriesDateMapper.TimeSeriesInterval.YEAR, timeSeries);
Assert.assertEquals(2, timeSeries.getValues().size());
Assert.assertEquals(Integer.valueOf(10), timeSeries.getValues().get(0).getValue());
}
}