Skip to content

Commit

Permalink
feat(openchallenges): filter challenges by input data types (EDAM Con…
Browse files Browse the repository at this point in the history
…cept IDs) (#2647)
  • Loading branch information
tschaffter authored Apr 23, 2024
1 parent 8295b82 commit 209357d
Show file tree
Hide file tree
Showing 24 changed files with 134 additions and 313 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/Eda
src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamConceptSearchQueryDto.java
src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamConceptSortDto.java
src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamConceptsPageDto.java
src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamDataDto.java
src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamOperationDto.java
src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/EdamSectionDto.java
src/main/java/org/sagebionetworks/openchallenges/challenge/service/model/dto/PageMetadataDto.java
Expand Down
4 changes: 2 additions & 2 deletions apps/openchallenges/challenge-service/requests.http
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ GET {{basePath}}/challenges?searchTerms=mortality%20dream

GET {{basePath}}/challenges?minStartDate=2017-01-01&maxStartDate=2017-12-31

### List the challenges that include the input data type 'genomic'.
### Get the challenges whose input data types include the EDAM concept ID 2 or 18

GET {{basePath}}/challenges?inputDataTypes=genomic
GET {{basePath}}/challenges?inputDataTypes=2,18

### List the challenges by category: featured

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ default ResponseEntity<ChallengeDto> getChallenge(Long challengeId) {
for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) {
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
String exampleString =
"{ \"avatarUrl\" : \"https://openchallenges.io\", \"endDate\" : \"2017-07-21T00:00:00.000+00:00\", \"description\" : \"This is an example description of the challenge.\", \"platform\" : { \"name\" : \"name\", \"id\" : 1, \"slug\" : \"example-challenge-platform\" }, \"starredCount\" : 100, \"createdAt\" : \"2022-07-04T22:19:11Z\", \"incentives\" : [ \"publication\", \"publication\" ], \"submissionTypes\" : [ \"container_image\", \"container_image\" ], \"websiteUrl\" : \"https://openchallenges.io\", \"name\" : \"name\", \"id\" : 1, \"categories\" : [ \"featured\", \"featured\" ], \"headline\" : \"Example challenge headline\", \"operation\" : { \"classId\" : \"http://edamontology.org/operation_0230\", \"preferredLabel\" : \"Sequence generation\" }, \"slug\" : \"awesome-challenge\", \"startDate\" : \"2017-07-21T00:00:00.000+00:00\", \"doi\" : \"https://doi.org/123/abc\", \"status\" : \"active\", \"inputDataTypes\" : [ { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\" }, { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\" } ], \"updatedAt\" : \"2022-07-04T22:19:11Z\" }";
"{ \"avatarUrl\" : \"https://openchallenges.io\", \"endDate\" : \"2017-07-21T00:00:00.000+00:00\", \"description\" : \"This is an example description of the challenge.\", \"platform\" : { \"name\" : \"name\", \"id\" : 1, \"slug\" : \"example-challenge-platform\" }, \"starredCount\" : 100, \"createdAt\" : \"2022-07-04T22:19:11Z\", \"incentives\" : [ \"publication\", \"publication\" ], \"submissionTypes\" : [ \"container_image\", \"container_image\" ], \"websiteUrl\" : \"https://openchallenges.io\", \"name\" : \"name\", \"id\" : 1, \"categories\" : [ \"featured\", \"featured\" ], \"headline\" : \"Example challenge headline\", \"operation\" : { \"classId\" : \"http://edamontology.org/operation_0230\", \"preferredLabel\" : \"Sequence generation\" }, \"slug\" : \"awesome-challenge\", \"startDate\" : \"2017-07-21T00:00:00.000+00:00\", \"doi\" : \"https://doi.org/123/abc\", \"status\" : \"active\", \"inputDataTypes\" : [ { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\", \"id\" : 1 }, { \"classId\" : \"http://edamontology.org/data_0850\", \"preferredLabel\" : \"Sequence set\", \"id\" : 1 } ], \"updatedAt\" : \"2022-07-04T22:19:11Z\" }";
ApiUtil.setExampleResponse(request, "application/json", exampleString);
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class ChallengeDto {

@JsonProperty("inputDataTypes")
@Valid
private List<EdamDataDto> inputDataTypes = null;
private List<EdamConceptDto> inputDataTypes = null;

@JsonProperty("categories")
@Valid
Expand Down Expand Up @@ -380,12 +380,12 @@ public void setSubmissionTypes(List<ChallengeSubmissionTypeDto> submissionTypes)
this.submissionTypes = submissionTypes;
}

public ChallengeDto inputDataTypes(List<EdamDataDto> inputDataTypes) {
public ChallengeDto inputDataTypes(List<EdamConceptDto> inputDataTypes) {
this.inputDataTypes = inputDataTypes;
return this;
}

public ChallengeDto addInputDataTypesItem(EdamDataDto inputDataTypesItem) {
public ChallengeDto addInputDataTypesItem(EdamConceptDto inputDataTypesItem) {
if (this.inputDataTypes == null) {
this.inputDataTypes = new ArrayList<>();
}
Expand All @@ -400,11 +400,11 @@ public ChallengeDto addInputDataTypesItem(EdamDataDto inputDataTypesItem) {
*/
@Valid
@Schema(name = "inputDataTypes", required = false)
public List<EdamDataDto> getInputDataTypes() {
public List<EdamConceptDto> getInputDataTypes() {
return inputDataTypes;
}

public void setInputDataTypes(List<EdamDataDto> inputDataTypes) {
public void setInputDataTypes(List<EdamConceptDto> inputDataTypes) {
this.inputDataTypes = inputDataTypes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public class ChallengeSearchQueryDto {
@Valid
private List<ChallengeSubmissionTypeDto> submissionTypes = null;

@JsonProperty("inputDataTypes")
@Valid
private List<Long> inputDataTypes = null;

@JsonProperty("categories")
@Valid
private List<ChallengeCategoryDto> categories = null;
Expand Down Expand Up @@ -379,6 +383,36 @@ public void setSubmissionTypes(List<ChallengeSubmissionTypeDto> submissionTypes)
this.submissionTypes = submissionTypes;
}

public ChallengeSearchQueryDto inputDataTypes(List<Long> inputDataTypes) {
this.inputDataTypes = inputDataTypes;
return this;
}

public ChallengeSearchQueryDto addInputDataTypesItem(Long inputDataTypesItem) {
if (this.inputDataTypes == null) {
this.inputDataTypes = new ArrayList<>();
}
this.inputDataTypes.add(inputDataTypesItem);
return this;
}

/**
* An array of EDAM concept ID used to filter the results.
*
* @return inputDataTypes
*/
@Schema(
name = "inputDataTypes",
description = "An array of EDAM concept ID used to filter the results.",
required = false)
public List<Long> getInputDataTypes() {
return inputDataTypes;
}

public void setInputDataTypes(List<Long> inputDataTypes) {
this.inputDataTypes = inputDataTypes;
}

public ChallengeSearchQueryDto categories(List<ChallengeCategoryDto> categories) {
this.categories = categories;
return this;
Expand Down Expand Up @@ -454,6 +488,7 @@ public boolean equals(Object o) {
&& Objects.equals(this.organizations, challengeSearchQuery.organizations)
&& Objects.equals(this.status, challengeSearchQuery.status)
&& Objects.equals(this.submissionTypes, challengeSearchQuery.submissionTypes)
&& Objects.equals(this.inputDataTypes, challengeSearchQuery.inputDataTypes)
&& Objects.equals(this.categories, challengeSearchQuery.categories)
&& Objects.equals(this.searchTerms, challengeSearchQuery.searchTerms);
}
Expand All @@ -473,6 +508,7 @@ public int hashCode() {
organizations,
status,
submissionTypes,
inputDataTypes,
categories,
searchTerms);
}
Expand All @@ -493,6 +529,7 @@ public String toString() {
sb.append(" organizations: ").append(toIndentedString(organizations)).append("\n");
sb.append(" status: ").append(toIndentedString(status)).append("\n");
sb.append(" submissionTypes: ").append(toIndentedString(submissionTypes)).append("\n");
sb.append(" inputDataTypes: ").append(toIndentedString(inputDataTypes)).append("\n");
sb.append(" categories: ").append(toIndentedString(categories)).append("\n");
sb.append(" searchTerms: ").append(toIndentedString(searchTerms)).append("\n");
sb.append("}");
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ public class ChallengeEntity {
inverseJoinColumns = @JoinColumn(name = "edam_concept_id"))
@IndexedEmbedded(
name = "input_data_types",
includePaths = {"class_id", "preferred_label"})
includePaths = {"id", "class_id", "preferred_label"})
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
private List<EdamDataEntity> inputDataTypes;
private List<EdamConceptEntity> inputDataTypes;

@OneToMany(mappedBy = "challenge", fetch = FetchType.LAZY)
@IndexedEmbedded(includePaths = {"name"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class ChallengeInputDataTypeEntity {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "edam_concept_id", nullable = false)
private EdamDataEntity edamData;
private EdamConceptEntity edamConcept;

@Column(name = "created_at")
private OffsetDateTime createdAt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class EdamConceptEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, updatable = false)
@GenericField(name = "id")
private Long id;

@Column(name = "class_id", nullable = false)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ChallengeMapper extends BaseMapper<ChallengeEntity, ChallengeDto> {

private SimpleChallengePlatformMapper platformMapper = new SimpleChallengePlatformMapper();
private EdamOperationMapper edamOperationMapper = new EdamOperationMapper();
private EdamDataMapper edamDataMapper = new EdamDataMapper();
private EdamConceptMapper edamConceptMapper = new EdamConceptMapper();

@Override
public ChallengeEntity convertToEntity(ChallengeDto dto, Object... args) {
Expand All @@ -31,10 +31,10 @@ public ChallengeEntity convertToEntity(ChallengeDto dto, Object... args) {
@Override
public ChallengeDto convertToDto(ChallengeEntity entity, Object... args) {
ChallengeDto dto = new ChallengeDto();
LOG.info("challenge dto initial: {}", dto);
LOG.trace("challenge dto initial: {}", dto);
if (entity != null) {
BeanUtils.copyProperties(entity, dto, "stars", "inputDataTypes", "platform", "operation");
LOG.info("challenge dto before set: {}", dto);
LOG.trace("challenge dto before set: {}", dto);
dto.setStatus(ChallengeStatusDto.fromValue(entity.getStatus()));
dto.setPlatform(platformMapper.convertToDto(entity.getPlatform()));
if (entity.getOperation() != null) {
Expand All @@ -52,9 +52,9 @@ public ChallengeDto convertToDto(ChallengeEntity entity, Object... args) {
entity.getCategories().stream()
.map(o -> ChallengeCategoryDto.fromValue(o.getName()))
.toList());
dto.inputDataTypes(edamDataMapper.convertToDtoList(entity.getInputDataTypes()));
dto.inputDataTypes(edamConceptMapper.convertToDtoList(entity.getInputDataTypes()));
dto.starredCount(entity.getStars().size());
LOG.info("challenge dto: {}", dto);
LOG.trace("challenge dto: {}", dto);
}
return dto;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ private SearchResult<ChallengeEntity> getSearchResult(
if (query.getSubmissionTypes() != null && !query.getSubmissionTypes().isEmpty()) {
predicates.add(getChallengeSubmissionTypesPredicate(pf, query));
}
if (query.getInputDataTypes() != null && !query.getInputDataTypes().isEmpty()) {
predicates.add(getInputDataTypesPredicate(pf, query));
}
if (query.getIncentives() != null && !query.getIncentives().isEmpty()) {
predicates.add(getChallengeIncentivesPredicate(pf, query));
}
Expand Down Expand Up @@ -167,6 +170,17 @@ private SearchPredicate getChallengeSubmissionTypesPredicate(
.toPredicate();
}

private SearchPredicate getInputDataTypesPredicate(
SearchPredicateFactory pf, ChallengeSearchQueryDto query) {
return pf.bool(
b -> {
for (Long edamConceptId : query.getInputDataTypes()) {
b.should(pf.match().field("input_data_types.id").matching(edamConceptId));
}
})
.toPredicate();
}

/**
* Matches the challenges whose at least one of their contributors is in the list of
* contributors/organizations specified.
Expand Down
Loading

0 comments on commit 209357d

Please sign in to comment.