Skip to content

Commit

Permalink
#96 | Search by Text concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
1t5j0y committed Apr 15, 2024
1 parent 34cd1eb commit 5082614
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 28 deletions.
25 changes: 18 additions & 7 deletions src/main/java/org/avniproject/etl/dto/ConceptFilterSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ public class ConceptFilterSearch {
private List<String> columnValues;
private String from;
private String to;
private boolean isNonStringValue;
private boolean nonStringValue;
private boolean exactSearch;

public ConceptFilterSearch(String tableName, String columnName, List<String> columnValues, String from, String to, boolean isNonStringValue) {
public ConceptFilterSearch(String tableName, String columnName, List<String> columnValues, String from, String to, boolean nonStringValue, boolean exactSearch) {
this.tableName = tableName;
this.columnName = columnName;
this.columnValues = columnValues;
this.from = from;
this.to = to;
this.isNonStringValue = isNonStringValue;
this.nonStringValue = nonStringValue;
this.exactSearch = exactSearch;
}

public String getTableName() {
Expand Down Expand Up @@ -51,7 +53,8 @@ public String toString() {
", columnValues=" + columnValues +
", from=" + from +
", to=" + to +
", isNonStringValue=" + isNonStringValue +
", nonStringValue=" + nonStringValue +
", exactSearch=" + exactSearch +
'}';
}

Expand All @@ -71,11 +74,19 @@ public void setTo(String to) {
this.to = to;
}

public boolean getNonStringValue() {
return isNonStringValue;
public boolean isNonStringValue() {
return nonStringValue;
}

public void setNonStringValue(boolean nonStringValue) {
isNonStringValue = nonStringValue;
this.nonStringValue = nonStringValue;
}

public boolean isExactSearch() {
return exactSearch;
}

public void setExactSearch(boolean exactSearch) {
this.exactSearch = exactSearch;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,19 @@ public class MediaTableRepository {
private List<ConceptFilterSearch> determineConceptFilterTablesAndColumns(List<ConceptFilter> conceptFilters) {
logger.debug("searching concepts: " + conceptFilters);
List<ConceptFilterSearch> conceptFilterTablesAndColumns = new ArrayList<>();
List<ColumnMetadata.ConceptType> supportedConceptSearchTypes = Arrays.asList(
List<ColumnMetadata.ConceptType> textConceptSearchTypes = Arrays.asList(
ColumnMetadata.ConceptType.Text,
ColumnMetadata.ConceptType.Id,
ColumnMetadata.ConceptType.Notes
);
List<ColumnMetadata.ConceptType> supportedConceptSearchTypes = new ArrayList<>(Arrays.asList(
ColumnMetadata.ConceptType.Numeric,
ColumnMetadata.ConceptType.Date,
ColumnMetadata.ConceptType.SingleSelect,
ColumnMetadata.ConceptType.MultiSelect
);
));
supportedConceptSearchTypes.addAll(textConceptSearchTypes);

SchemaMetadata schema = schemaMetadataRepository.getExistingSchemaMetadata();
List<TableMetadata> tablesToSearch = Stream.of(schema.getAllSubjectTables(),
schema.getAllProgramEnrolmentTables(),
Expand All @@ -53,9 +60,9 @@ private List<ConceptFilterSearch> determineConceptFilterTablesAndColumns(List<Co
.flatMap(Collection::stream)
.toList();
logger.debug("Searching tables: " + tablesToSearch);
for (ConceptFilter conceptFilter: conceptFilters) {
for (ConceptFilter conceptFilter : conceptFilters) {
String conceptUuid = conceptFilter.getConceptUuid();
for (TableMetadata tableMetadata: tablesToSearch) {
for (TableMetadata tableMetadata : tablesToSearch) {
Optional<ColumnMetadata> column = tableMetadata.getColumnMetadataList()
.stream()
.filter(columnMetadata -> Objects.equals(columnMetadata.getConceptUuid(), conceptUuid)
Expand All @@ -66,7 +73,8 @@ private List<ConceptFilterSearch> determineConceptFilterTablesAndColumns(List<Co
conceptFilterTablesAndColumns.add(new ConceptFilterSearch(tableMetadata.getName(),
columnMetadata.getName(), conceptFilter.getValues(),
conceptFilter.getFrom(), conceptFilter.getTo(),
columnMetadata.getConceptType().equals(ColumnMetadata.ConceptType.Numeric)));
columnMetadata.getConceptType().equals(ColumnMetadata.ConceptType.Numeric),
!textConceptSearchTypes.contains(columnMetadata.getConceptType())));
break;
}
}
Expand All @@ -86,12 +94,12 @@ private <T> List<T> searchInternal(MediaSearchRequest mediaSearchRequest, Page p
}

Query query = new MediaSearchQueryBuilder()
.withPage(page)
.withMediaSearchRequest(mediaSearchRequest)
.withSearchConceptFilters(conceptFilterSearches)
.build();
.withPage(page)
.withMediaSearchRequest(mediaSearchRequest)
.withSearchConceptFilters(conceptFilterSearches)
.build();
return runInSchemaUserContext(() -> new NamedParameterJdbcTemplate(jdbcTemplate)
.query(query.sql(), query.parameters(), rowMapper), jdbcTemplate);
.query(query.sql(), query.parameters(), rowMapper), jdbcTemplate);
}


Expand Down
26 changes: 15 additions & 11 deletions src/main/resources/sql/api/searchMedia.sql.st
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,21 @@ SELECT media.id as id,
FROM <schemaName>.media media
JOIN <schemaName>.address address ON address.id = media.address_id
<if(joinTablesAndColumns)>
<joinTablesAndColumns:{joinTableAndColumn |
RIGHT JOIN <schemaName>.<joinTableAndColumn.tableName> <joinTableAndColumn.tableName>_<i0> ON media.entity_id = <joinTableAndColumn.tableName>_<i0>.id
AND <joinTableAndColumn.tableName>_<i0>."<joinTableAndColumn.columnName>"
<if(joinTableAndColumn.columnValues)>
IN ('<joinTableAndColumn.columnValues:{columnValue | <columnValue>}; separator="', '">')
<else>
<! BETWEEN <if(joinTableAndColumn.isNonStringValue)>if <joinTableAndColumn.from> AND <joinTableAndColumn.to><else> else '<joinTableAndColumn.from>' AND '<joinTableAndColumn.to>'<endif> !>
<! Below works because postgresql does an implicit type cast to numeric on passing strings for comparing with numeric. Revert to above approach after fixing (currently isNonStringValue is always false despite setting boolean) if this causes issues later. !>
BETWEEN '<joinTableAndColumn.from>' AND '<joinTableAndColumn.to>'
<endif>
}; separator="\n">
<joinTablesAndColumns:{joinTableAndColumn |
RIGHT JOIN <schemaName>.<joinTableAndColumn.tableName> <joinTableAndColumn.tableName> ON media.entity_id = <joinTableAndColumn.tableName>.id
<if(joinTableAndColumn.exactSearch)>
AND <joinTableAndColumn.tableName>."<joinTableAndColumn.columnName>"
<if(joinTableAndColumn.columnValues)>
IN ('<joinTableAndColumn.columnValues:{columnValue | <columnValue>}; separator="', '">')
<else>
<! BETWEEN <if(joinTableAndColumn.nonStringValue)>if <joinTableAndColumn.from> AND <joinTableAndColumn.to><else> else '<joinTableAndColumn.from>' AND '<joinTableAndColumn.to>'<endif> !>
<! Below works because postgresql does an implicit type cast to numeric on passing strings for comparing with numeric. Revert to above approach after fixing (currently nonStringValue is always false despite setting boolean) if this causes issues later. !>
BETWEEN '<joinTableAndColumn.from>' AND '<joinTableAndColumn.to>'
<endif>
<else>
AND <joinTableAndColumn.columnValues:{columnValue | <joinTableAndColumn.tableName>."<joinTableAndColumn.columnName>" ILIKE '%<columnValue>%'}; separator=" \nAND ">
<endif>
}; separator="\n">
<endif>
where media.image_url is not null
and media.is_voided is false
Expand Down

0 comments on commit 5082614

Please sign in to comment.