Add to/from start/end year for projects && fix date ranges

This commit is contained in:
Serafeim Chatzopoulos 2024-06-13 18:12:04 +03:00
parent 695048b515
commit f195d1c58d
7 changed files with 100 additions and 58 deletions

View File

@ -19,10 +19,10 @@ public class DataSourceRequest {
@Parameter(description = "The official name of the data source", schema = @Schema(type = "string")) @Parameter(description = "The official name of the data source", schema = @Schema(type = "string"))
private String[] officialName; private String[] officialName;
//
@Parameter(description = "The English name of the data source", array = @ArraySchema(schema = @Schema(type = "string"))) @Parameter(description = "The English name of the data source", array = @ArraySchema(schema = @Schema(type = "string")))
private String[] englishName; private String[] englishName;
//
// @Parameter(description = "The legal name of the organization in short form", array = @ArraySchema(schema = @Schema(type = "string"))) // @Parameter(description = "The legal name of the organization in short form", array = @ArraySchema(schema = @Schema(type = "string")))
// private String[] legalShortName; // private String[] legalShortName;
@ -47,13 +47,9 @@ public class DataSourceRequest {
@Parameter(description = "Retrieve data sources connected to the community (with OpenAIRE id)", array = @ArraySchema(schema = @Schema(type = "string"))) @Parameter(description = "Retrieve data sources connected to the community (with OpenAIRE id)", array = @ArraySchema(schema = @Schema(type = "string")))
private String[] relCommunityId; private String[] relCommunityId;
@Parameter(description = "Retrieve data sources collected from the data source (with OpenAIRE id)", array = @ArraySchema(schema = @Schema(type = "string"))) @Parameter(description = "Retrieve data sources collected from the data source (with OpenAIRE id)", array = @ArraySchema(schema = @Schema(type = "string")))
private String[] relCollectedFromDatasourceId; private String[] relCollectedFromDatasourceId;
// @Parameter(description = "The country code of the organization", array = @ArraySchema(schema = @Schema(type = "string")))
// private String[] countryCode;
@Min(value = 1) @Min(value = 1)
@Parameter(description = "Page number of the results", schema = @Schema(defaultValue = "1", type = "integer")) @Parameter(description = "Page number of the results", schema = @Schema(defaultValue = "1", type = "integer"))
private int page = 1; private int page = 1;
@ -63,8 +59,8 @@ public class DataSourceRequest {
@Parameter(description = "Number of results per page", schema = @Schema(defaultValue = "10", type = "integer")) @Parameter(description = "Number of results per page", schema = @Schema(defaultValue = "10", type = "integer"))
private int pageSize = 10; private int pageSize = 10;
@Parameter(description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, organizations can be only sorted by the 'score'." , schema = @Schema(defaultValue = "score DESC")) @Parameter(description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, organizations can be only sorted by the 'relevance'." , schema = @Schema(defaultValue = "relevance DESC"))
@Pattern(regexp = "^((score)\\s+(ASC|DESC),?\\s*)+$", message = "The field should be in the format 'fieldname ASC|DESC', organizations can be only sorted by the 'score'.") @Pattern(regexp = "^((relevance)\\s+(ASC|DESC),?\\s*)+$", message = "The field should be in the format 'fieldname ASC|DESC', organizations can be only sorted by the 'relevance'.")
private String sortBy; private String sortBy;

View File

@ -47,9 +47,8 @@ public class OrganizationRequest {
@Parameter(description = "Number of results per page", schema = @Schema(defaultValue = "10", type = "integer")) @Parameter(description = "Number of results per page", schema = @Schema(defaultValue = "10", type = "integer"))
private int pageSize = 10; private int pageSize = 10;
@Parameter(description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, organizations can be only sorted by the 'score'." , schema = @Schema(defaultValue = "score DESC")) @Parameter(description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, organizations can be only sorted by the 'relevance'." , schema = @Schema(defaultValue = "relevance DESC"))
@Pattern(regexp = "^((score)\\s+(ASC|DESC),?\\s*)+$", message = "The field should be in the format 'fieldname ASC|DESC', organizations can be only sorted by the 'score'.") @Pattern(regexp = "^((relevance)\\s+(ASC|DESC),?\\s*)+$", message = "The field should be in the format 'fieldname ASC|DESC', organizations can be only sorted by the 'relevance'.")
private String sortBy; private String sortBy;
} }

View File

@ -9,6 +9,9 @@ import jakarta.validation.constraints.Pattern;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
@Getter @Getter
@Setter @Setter
@ -41,11 +44,21 @@ public class ProjectRequest {
@Parameter(description = "The identifier of the funding stream" , array = @ArraySchema(schema = @Schema(type = "string"))) @Parameter(description = "The identifier of the funding stream" , array = @ArraySchema(schema = @Schema(type = "string")))
private String[] fundingStreamId; private String[] fundingStreamId;
@Parameter(description = "The year that the project started", array = @ArraySchema(schema = @Schema(type = "integer"))) @Parameter(description = "Gets the projects with start date greater than or equal to the given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date"))
private Integer[] startYear; @DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate fromStartDate;
@Parameter(description = "The end year of the project", array = @ArraySchema(schema = @Schema(type = "integer"))) @Parameter(description = "Gets the projects with start date less than or equal to the given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date"))
private Integer[] endYear; @DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate toStartDate;
@Parameter(description = "Gets the projects with end date greater than or equal to the given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date"))
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate fromEndDate;
@Parameter(description = "Gets the projects with end date less than or equal to the given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date"))
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate toEndDate;
@Parameter(description = "The name of the related organization", array = @ArraySchema(schema = @Schema(type = "string"))) @Parameter(description = "The name of the related organization", array = @ArraySchema(schema = @Schema(type = "string")))
private String[] relOrganizationName; private String[] relOrganizationName;
@ -71,7 +84,7 @@ public class ProjectRequest {
@Parameter(description = "Number of results per page", schema = @Schema(defaultValue = "10", type = "integer")) @Parameter(description = "Number of results per page", schema = @Schema(defaultValue = "10", type = "integer"))
private int pageSize = 10; private int pageSize = 10;
@Parameter(description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, where fieldname is one of 'score', 'projectstartdate', 'projectstartyear', 'projectenddate', 'projectendyear', 'projectduration'. Multiple sorting parameters should be comma-separated." , schema = @Schema(defaultValue = "score DESC")) @Parameter(description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, where fieldname is one of 'relevance', 'projectstartyear', 'projectendyear'. Multiple sorting parameters should be comma-separated." , schema = @Schema(defaultValue = "relevance DESC"))
@Pattern(regexp = "^((score|projectstartdate|projectstartyear|projectenddate|projectendyear|projectduration)\\s+(ASC|DESC),?\\s*)+$", message = "The field should be in the format 'fieldname ASC|DESC', where fieldname is one of 'score', 'projectstartdate', 'projectstartyear', 'projectenddate', 'projectendyear', 'projectduration'. Multiple sorting parameters should be comma-separated.") @Pattern(regexp = "^((relevance|projectstartyear|projectendyear)\\s+(ASC|DESC),?\\s*)+$", message = "The field should be in the format 'fieldname ASC|DESC', where fieldname is one of 'score', 'projectstartyear', 'projectendyear'. Multiple sorting parameters should be comma-separated.")
private String sortBy; private String sortBy;
} }

View File

@ -11,7 +11,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date; import java.time.LocalDate;
@Getter @Getter
@Setter @Setter
@ -39,13 +39,13 @@ public class ResearchProductsRequest {
@Parameter(description = "The type of the research product", array = @ArraySchema(schema = @Schema(type = "string", allowableValues = {"publication", "dataset", "software", "other"}))) @Parameter(description = "The type of the research product", array = @ArraySchema(schema = @Schema(type = "string", allowableValues = {"publication", "dataset", "software", "other"})))
private String[] type; private String[] type;
@Parameter(description = "Gets the research products whose publication date is greater than or equal the given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date")) @Parameter(description = "Gets the research products whose publication date is greater than or equal to he given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date"))
@DateTimeFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd")
private Date fromPublicationDate; private LocalDate fromPublicationDate;
@Parameter(description = "Gets the research products whose publication date is less than or equal the given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date")) @Parameter(description = "Gets the research products whose publication date is less than or equal to the given date. Please provide a date formatted as YYYY-MM-DD", schema = @Schema(type = "string", format = "date"))
@DateTimeFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd")
private Date toPublicationDate; private LocalDate toPublicationDate;
@Parameter(description = "List of subjects associated to the research product", array = @ArraySchema(schema = @Schema(type = "string"))) @Parameter(description = "List of subjects associated to the research product", array = @ArraySchema(schema = @Schema(type = "string")))
private String[] subjects; private String[] subjects;

View File

@ -3,6 +3,11 @@ package eu.openaire.api.mappers;
import eu.openaire.api.errors.exceptions.BadRequestException; import eu.openaire.api.errors.exceptions.BadRequestException;
import org.apache.solr.client.solrj.util.ClientUtils; import org.apache.solr.client.solrj.util.ClientUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -110,4 +115,39 @@ public class Utils {
return str == null || str.length == 0; return str == null || str.length == 0;
} }
static private String formatDate(LocalDate date) {
// IMPORTANT: all dates are indexed in 12:00:00 in the index (not sure why)
// so we need to set this time to the date (this should change if dates are indexed in a different way)
int hour = 12;
int minute = 0;
int second = 0;
LocalDateTime localDateTime = date.atTime(hour, minute, second);
// Convert LocalDateTime to ZonedDateTime in UTC
ZonedDateTime zdt = localDateTime.atZone(ZoneOffset.UTC);
// Define the desired format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
// Format the ZonedDateTime to the desired string
return zdt.format(formatter);
}
static public String formatSolrDateRange(String fieldName, LocalDate fromDate, LocalDate toDate) {
if (fromDate != null && toDate != null) {
return String.format(fieldName, Utils.formatDate(fromDate), Utils.formatDate(toDate));
} else {
if (fromDate != null) {
return String.format(fieldName, Utils.formatDate(fromDate), "*");
}
if (toDate != null) {
return String.format(fieldName, "*", Utils.formatDate(toDate));
}
}
return null;
}
} }

View File

@ -1,13 +1,13 @@
package eu.openaire.api.mappers.query; package eu.openaire.api.mappers.query;
import eu.openaire.api.mappers.Utils;
import eu.openaire.api.dto.request.ProjectRequest; import eu.openaire.api.dto.request.ProjectRequest;
import eu.openaire.api.mappers.Utils;
import eu.openaire.api.solr.SolrQueryParams; import eu.openaire.api.solr.SolrQueryParams;
import org.mapstruct.*; import org.mapstruct.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Optional;
@Mapper(componentModel = "spring") @Mapper(componentModel = "spring")
public interface ProjectRequestMapper { public interface ProjectRequestMapper {
@ -39,8 +39,8 @@ public interface ProjectRequestMapper {
Map.entry("fundingStreamId", "fundinglevel0_name:(%s) OR fundinglevel1_name:(%s) OR fundinglevel2_name:(%s)"), Map.entry("fundingStreamId", "fundinglevel0_name:(%s) OR fundinglevel1_name:(%s) OR fundinglevel2_name:(%s)"),
Map.entry("callIdentifier", "projectcallidentifier:(%s)"), Map.entry("callIdentifier", "projectcallidentifier:(%s)"),
Map.entry("startYear", "projectstartyear:(%s)"), Map.entry("startDate", "projectstartdate:[%s TO %s]"),
Map.entry("endYear", "projectendyear:(%s)"), Map.entry("endDate", "projectenddate:[%s TO %s]"),
// filter by related entity fields // filter by related entity fields
Map.entry("relCommunityId", "communityid:(%s)"), Map.entry("relCommunityId", "communityid:(%s)"),
@ -124,25 +124,27 @@ public interface ProjectRequestMapper {
fqList.add(String.format(solrFieldMapping.get("relCollectedFromDatasourceId"), Utils.escapeAndJoin(src.getRelCollectedFromDatasourceId(), "OR", false))); fqList.add(String.format(solrFieldMapping.get("relCollectedFromDatasourceId"), Utils.escapeAndJoin(src.getRelCollectedFromDatasourceId(), "OR", false)));
} }
if (src.getStartYear() != null) { // add start year range filter
Optional.ofNullable(
Utils.formatSolrDateRange(
solrFieldMapping.get("startDate"),
src.getFromStartDate(),
src.getToStartDate()
)
).ifPresent(fqList::add);
String[] startYearValues = Arrays.stream(src.getStartYear()) // add end year range filter
.map(String::valueOf) Optional.ofNullable(
.toArray(String[]::new); Utils.formatSolrDateRange(
solrFieldMapping.get("endDate"),
fqList.add(String.format(solrFieldMapping.get("startYear"), Utils.escapeAndJoin(startYearValues, "OR", false))); src.getFromEndDate(),
} src.getToEndDate()
)
if (src.getEndYear() != null) { ).ifPresent(fqList::add);
String[] endYearValues = Arrays.stream(src.getEndYear())
.map(String::valueOf)
.toArray(String[]::new);
fqList.add(String.format(solrFieldMapping.get("endYear"), Utils.escapeAndJoin(endYearValues, "OR", false)));
}
solrQueryParams.setFq(fqList); solrQueryParams.setFq(fqList);
System.out.println(solrQueryParams.toString());
} }
} }

View File

@ -5,10 +5,10 @@ import eu.openaire.api.mappers.Utils;
import eu.openaire.api.solr.SolrQueryParams; import eu.openaire.api.solr.SolrQueryParams;
import org.mapstruct.*; import org.mapstruct.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Optional;
@Mapper(componentModel = "spring") @Mapper(componentModel = "spring")
public interface ResearchProductsRequestMapper { public interface ResearchProductsRequestMapper {
@ -240,21 +240,13 @@ public interface ResearchProductsRequestMapper {
} }
// publication date // publication date
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); Optional.ofNullable(
Utils.formatSolrDateRange(
if (src.getFromPublicationDate() != null && src.getToPublicationDate() != null) { solrFieldMapping.get("publicationDate"),
fqList.add(String.format(solrFieldMapping.get("publicationDate"), formatter.format(src.getFromPublicationDate()), formatter.format(src.getToPublicationDate()))); src.getFromPublicationDate(),
} else { src.getToPublicationDate()
if (src.getFromPublicationDate() != null) { )
fqList.add(String.format(solrFieldMapping.get("publicationDate"), formatter.format(src.getFromPublicationDate()), "*")); ).ifPresent(fqList::add);
}
if (src.getToPublicationDate() != null) {
fqList.add(String.format(solrFieldMapping.get("publicationDate"), "*", formatter.format(src.getToPublicationDate())));
}
}
solrQueryParams.setFq(fqList); solrQueryParams.setFq(fqList);
} }