Skip to content

Commit bdbdbc4

Browse files
authored
Simplified 'samplesByDate' query (#1803)
Sample Metadata use of timestamps instead of formatted dates Request Metadata use of timestamps instead of formatted dates Update migration.cypher with timestamp conversion Added unit test for confirming latest metadata Updated query for samples by import date Signed-off-by: Angelica Ochoa <15623749+ao508@users.noreply.github.com>
1 parent 610679d commit bdbdbc4

File tree

14 files changed

+76
-70
lines changed

14 files changed

+76
-70
lines changed

model/src/main/java/org/mskcc/smile/model/RequestMetadata.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class RequestMetadata implements Serializable, Comparable<RequestMetadata
1313
private Long id;
1414
private String igoRequestId;
1515
private String requestMetadataJson;
16-
private String importDate;
16+
private Long importDate;
1717
@Relationship(type = "HAS_STATUS", direction = Relationship.Direction.OUTGOING)
1818
private Status status;
1919

@@ -23,7 +23,7 @@ public class RequestMetadata implements Serializable, Comparable<RequestMetadata
2323
* @param requestMetadataJson
2424
* @param importDate
2525
*/
26-
public RequestMetadata(String igoRequestId, String requestMetadataJson, String importDate) {
26+
public RequestMetadata(String igoRequestId, String requestMetadataJson, Long importDate) {
2727
this.igoRequestId = igoRequestId;
2828
this.requestMetadataJson = requestMetadataJson;
2929
this.importDate = importDate;
@@ -53,11 +53,11 @@ public void setRequestMetadataJson(String requestMetadataJson) {
5353
this.requestMetadataJson = requestMetadataJson;
5454
}
5555

56-
public String getImportDate() {
56+
public Long getImportDate() {
5757
return importDate;
5858
}
5959

60-
public void setImportDate(String importDate) {
60+
public void setImportDate(Long importDate) {
6161
this.importDate = importDate;
6262
}
6363

model/src/main/java/org/mskcc/smile/model/SampleMetadata.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public class SampleMetadata implements Serializable, Comparable<SampleMetadata>,
3434
private String cmoSampleName;
3535
private String sampleName;
3636
private String igoRequestId;
37-
private String importDate;
37+
private Long importDate;
3838
private String cmoInfoIgoId;
3939
private String oncotreeCode;
4040
private String collectionYear;
@@ -124,11 +124,11 @@ public void setId(Long id) {
124124
this.id = id;
125125
}
126126

127-
public String getImportDate() {
127+
public Long getImportDate() {
128128
return importDate;
129129
}
130130

131-
public void setImportDate(String importDate) {
131+
public void setImportDate(Long importDate) {
132132
this.importDate = importDate;
133133
}
134134

model/src/main/java/org/mskcc/smile/model/web/PublishedSmileSample.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class PublishedSmileSample {
3030
private String sampleName;
3131
private String cmoInfoIgoId;
3232
private String investigatorSampleId;
33-
private String importDate;
33+
private Long importDate;
3434
private String sampleType;
3535
private String oncotreeCode;
3636
private String collectionYear;
@@ -113,11 +113,11 @@ public void setSmileSampleId(UUID smileSampleId) {
113113
this.smileSampleId = smileSampleId;
114114
}
115115

116-
public String getImportDate() {
116+
public Long getImportDate() {
117117
return importDate;
118118
}
119119

120-
public void setImportDate(String importDate) {
120+
public void setImportDate(Long importDate) {
121121
this.importDate = importDate;
122122
}
123123

model/src/main/java/org/mskcc/smile/model/web/SmileSampleIdMapping.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.util.UUID;
44
import org.apache.commons.lang.builder.ToStringBuilder;
5-
import org.mskcc.smile.model.SampleMetadata;
65
import org.neo4j.ogm.annotation.typeconversion.Convert;
76
import org.neo4j.ogm.typeconversion.UuidStringConverter;
87

@@ -22,18 +21,6 @@ public class SmileSampleIdMapping {
2221
*/
2322
public SmileSampleIdMapping() {}
2423

25-
/**
26-
* SmileSampleIdMapping constructor.
27-
* @param smileSampleId
28-
* @param sampleMetadata
29-
*/
30-
public SmileSampleIdMapping(UUID smileSampleId, SampleMetadata sampleMetadata) {
31-
this.smileSampleId = smileSampleId;
32-
this.importDate = sampleMetadata.getImportDate();
33-
this.primaryId = sampleMetadata.getPrimaryId();
34-
this.cmoSampleName = sampleMetadata.getCmoSampleName();
35-
}
36-
3724
public UUID getSmileSampleId() {
3825
return smileSampleId;
3926
}

persistence/src/main/java/org/mskcc/smile/persistence/neo4j/SmileRequestRepository.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
public interface SmileRequestRepository extends Neo4jRepository<SmileRequest, Long> {
1818
@Query("""
1919
MATCH (r: Request {igoRequestId: $reqId})
20-
RETURN r
20+
OPTIONAL MATCH (r)-[hm:HAS_METADATA]->(rm: RequestMetadata)-[hs:HAS_STATUS]->(rs: Status)
21+
RETURN r, rm, rs, hm, hs
2122
""")
2223
SmileRequest findRequestById(@Param("reqId") String reqId);
2324

@@ -36,10 +37,11 @@ public interface SmileRequestRepository extends Neo4jRepository<SmileRequest, Lo
3637
List<RequestMetadata> findRequestMetadataHistoryByRequestId(@Param("reqId") String reqId);
3738

3839
@Query("""
39-
MATCH (r: Request)-[:HAS_METADATA]->(rm: RequestMetadata)
40+
MATCH (r: Request)-[hm:HAS_METADATA]->(rm: RequestMetadata)
4041
WHERE $dateRangeStart <= [rm][0].importDate <= $dateRangeEnd
41-
RETURN DISTINCT [r.smileRequestId, r.igoProjectId, r.igoRequestId]
42+
RETURN DISTINCT ({smileRequestId: r.smileRequestId,
43+
projectId: r.igoProjectId, requestId: r.igoRequestId})
4244
""")
43-
List<List<String>> findRequestWithinDateRange(@Param("dateRangeStart") String startDate,
44-
@Param("dateRangeEnd") String endDate);
45+
List<Object> findRequestWithinDateRange(@Param("dateRangeStart") Long startDate,
46+
@Param("dateRangeEnd") Long endDate);
4547
}

persistence/src/main/java/org/mskcc/smile/persistence/neo4j/SmileSampleRepository.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ void updateSamplePatientRelationship(@Param("smileSampleId") UUID smileSampleId,
116116
@Query("""
117117
MATCH (s: Sample {sampleCategory: 'research'})-[:HAS_METADATA]->(sm: SampleMetadata)
118118
WHERE sm.importDate >= $inputDate
119-
RETURN DISTINCT s.smileSampleId
119+
RETURN DISTINCT ({smileSampleId: s.smileSampleId,
120+
importDate: apoc.date.format(sm.importDate, "ms", "yyyy-MM-dd"),
121+
primaryId: sm.primaryId, cmoSampleName: sm.cmoSampleName})
120122
""")
121-
List<UUID> findSamplesByLatestImportDate(@Param("inputDate") String inputDate);
123+
List<Object> findSamplesByLatestImportDate(@Param("inputDate") Long inputDate);
122124

123125
@Query("""
124126
MATCH (s: Sample {smileSampleId: $smileSampleId})-[:HAS_METADATA]->(sm: SampleMetadata)

scripts/migrate.cypher

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,9 @@ WHERE cc.importDate IS NULL
188188
SET cc.importDate = apoc.date.parse(cc.date, "ms", "yyyy-MM-dd HH:mm")
189189
return cc
190190

191+
// convert dates to timestamps for request and sample metadata nodes
192+
MATCH (rm: RequestMetadata)
193+
SET rm.importDate = apoc.date.parse(rm.importDate, "ms", "yyyy-MM-dd")
194+
195+
MATCH (sm: SampleMetadata)
196+
SET sm.importDate = apoc.date.parse(sm.importDate, "ms", "yyyy-MM-dd")

service/src/main/java/org/mskcc/smile/service/impl/RequestServiceImpl.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.time.LocalDateTime;
88
import java.time.format.DateTimeFormatter;
99
import java.util.ArrayList;
10+
import java.util.Arrays;
1011
import java.util.Date;
1112
import java.util.List;
1213
import org.apache.commons.lang3.StringUtils;
@@ -104,10 +105,6 @@ public SmileRequest getSmileRequestById(String requestId) throws Exception {
104105
if (request == null) {
105106
return null;
106107
}
107-
// get request metadata and sample metadata for request if exists
108-
List<RequestMetadata> requestMetadataList =
109-
requestRepository.findRequestMetadataHistoryByRequestId(requestId);
110-
request.setRequestMetadataList(requestMetadataList);
111108
List<SmileSample> smileSampleList = sampleService.getResearchSamplesByRequestId(requestId);
112109
request.setSmileSampleList(smileSampleList);
113110
return request;
@@ -212,7 +209,7 @@ public List<RequestSummary> getRequestsByDate(String startDate, String endDate)
212209
}
213210
if (StringUtils.isBlank(endDate)) {
214211
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
215-
LocalDateTime now = LocalDateTime.now();
212+
LocalDateTime now = LocalDateTime.now().plusDays(1L); // inclusive of whole day
216213
endDate = dtf.format(now);
217214
}
218215
// get formatted dates and validate inputs
@@ -223,9 +220,9 @@ public List<RequestSummary> getRequestsByDate(String startDate, String endDate)
223220
throw new RuntimeException("Start date " + startDate + " cannot occur after end date "
224221
+ endDate);
225222
}
226-
227-
return transformRequestSummaryResults(
228-
requestRepository.findRequestWithinDateRange(startDate, endDate));
223+
List<Object> requests = requestRepository.findRequestWithinDateRange(
224+
formattedStartDate.toInstant().toEpochMilli(), formattedEndDate.toInstant().toEpochMilli());
225+
return Arrays.asList(mapper.convertValue(requests, RequestSummary[].class));
229226
}
230227

231228
@Override
@@ -246,14 +243,6 @@ private Date getFormattedDate(String dateString) {
246243
}
247244
}
248245

249-
private List<RequestSummary> transformRequestSummaryResults(List<List<String>> results) {
250-
List<RequestSummary> requestSummaryList = new ArrayList<>();
251-
for (List<String> result : results) {
252-
requestSummaryList.add(new RequestSummary(result));
253-
}
254-
return requestSummaryList;
255-
}
256-
257246
private DateFormat initDateFormatter() {
258247
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
259248
df.setLenient(Boolean.FALSE);

service/src/main/java/org/mskcc/smile/service/impl/SampleServiceImpl.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package org.mskcc.smile.service.impl;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import java.text.DateFormat;
5+
import java.text.ParseException;
6+
import java.text.SimpleDateFormat;
7+
import java.time.format.DateTimeFormatter;
48
import java.util.ArrayList;
9+
import java.util.Arrays;
10+
import java.util.Date;
511
import java.util.List;
612
import java.util.Map;
713
import java.util.UUID;
14+
import java.util.logging.Level;
15+
import java.util.logging.Logger;
816
import java.util.regex.Matcher;
917
import java.util.regex.Pattern;
1018
import org.apache.commons.lang3.StringUtils;
@@ -437,17 +445,20 @@ public List<SmileSampleIdMapping> getSamplesByDate(String importDate) {
437445
if (StringUtils.isBlank(importDate)) {
438446
throw new RuntimeException("Start date " + importDate + " cannot be null or empty");
439447
}
440-
// return latest sample metadata for each sample uuid returned
441-
List<UUID> sampleIds = sampleRepository.findSamplesByLatestImportDate(importDate);
442-
if (sampleIds == null) {
443-
return null;
444-
}
445-
List<SmileSampleIdMapping> sampleIdsList = new ArrayList<>();
446-
for (UUID smileSampleId : sampleIds) {
447-
SampleMetadata sm = sampleRepository.findLatestSampleMetadataBySmileId(smileSampleId);
448-
sampleIdsList.add(new SmileSampleIdMapping(smileSampleId, sm));
448+
449+
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
450+
try {
451+
Date formattedDate = df.parse(importDate);
452+
List<Object> sampleIds = sampleRepository.findSamplesByLatestImportDate(
453+
formattedDate.toInstant().toEpochMilli());
454+
if (sampleIds == null) {
455+
return null;
456+
}
457+
return Arrays.asList(mapper.convertValue(sampleIds, SmileSampleIdMapping[].class));
458+
} catch (ParseException ex) {
459+
LOG.error("Could not parse input date string as yyyy-MM-dd: " + importDate);
460+
throw new RuntimeException(ex);
449461
}
450-
return sampleIdsList;
451462
}
452463

453464
@Override

service/src/main/java/org/mskcc/smile/service/util/RequestDataFactory.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import com.fasterxml.jackson.core.JsonProcessingException;
44
import com.fasterxml.jackson.databind.JsonMappingException;
55
import com.fasterxml.jackson.databind.ObjectMapper;
6-
import java.time.LocalDateTime;
7-
import java.time.format.DateTimeFormatter;
6+
import java.time.Instant;
87
import java.util.ArrayList;
98
import java.util.Arrays;
109
import java.util.List;
@@ -94,7 +93,7 @@ private static RequestMetadata extractRequestMetadataFromJson(String requestMeta
9493
RequestMetadata requestMetadata = new RequestMetadata(
9594
requestId.toString(),
9695
mapper.writeValueAsString(requestMetadataMap),
97-
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE));
96+
Instant.now().toEpochMilli());
9897
requestMetadata.setStatus(extractStatusFromJson(requestMetadataJson));
9998
return requestMetadata;
10099
}

0 commit comments

Comments
 (0)