diff --git a/src/main/java/uk/ac/cam/cl/dtg/isaac/api/EventsFacade.java b/src/main/java/uk/ac/cam/cl/dtg/isaac/api/EventsFacade.java index 7a89602d32..5702775924 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/isaac/api/EventsFacade.java +++ b/src/main/java/uk/ac/cam/cl/dtg/isaac/api/EventsFacade.java @@ -566,7 +566,7 @@ eventId, new Date(), currentUser.getGivenName(), if (schoolId != null) { School school = schoolListReader.findSchoolById(schoolId); if (null != school) { - resultRow.add(school.getName()); + resultRow.add(school.getSchoolName()); } else { resultRow.add(schoolId); } diff --git a/src/main/java/uk/ac/cam/cl/dtg/isaac/dos/users/School.java b/src/main/java/uk/ac/cam/cl/dtg/isaac/dos/users/School.java index 7190885c96..fce86d8d03 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/isaac/dos/users/School.java +++ b/src/main/java/uk/ac/cam/cl/dtg/isaac/dos/users/School.java @@ -20,16 +20,19 @@ * */ public class School { - private String urn; - private String name; - private String postcode; + private String schoolId; + private String countryCode; + private String schoolName; + private String town; + private String postalCode; + private Boolean excluded; private Boolean closed; /** * Enum to represent where this school object was created. */ public enum SchoolDataSource { - GOVERNMENT_UK, GOVERNMENT_IE, GOVERNMENT_SCO, GOVERNMENT_WAL, GOVERNMENT_NI, USER_ENTERED; + GOVERNMENT_UK, GOVERNMENT_IE, GOVERNMENT_SCT, GOVERNMENT_SCT_IND, GOVERNMENT_WLS, GOVERNMENT_NIR, USER_ENTERED; @Override public String toString() { @@ -48,90 +51,156 @@ public School() { /** * Full constructor. - * - * @param urn - * - unique id - * @param name - * - name of the school. - * @param postcode - * -postcode of the school - * @param dataSource - * -dataSource of this information + * + * @param schoolId + * - unique school ID + * @param countryCode + * - country code for the school + * @param schoolName + * - name of the school + * @param town + * - name of the town where the school is located + * @param postalCode + * - postal code of the school + * @param excluded + * - whether the school is excluded when searching for schools by name * @param closed * - whether the school is closed + * @param dataSource + * - data source of this information */ - public School(final String urn, final String name, final String postcode, final Boolean closed, final SchoolDataSource dataSource) { - this.urn = urn; - this.name = name; - this.postcode = postcode; - this.dataSource = dataSource; + public School(final String schoolId, final String countryCode, final String schoolName, final String town, + final String postalCode, final Boolean excluded, final Boolean closed, final SchoolDataSource dataSource) { + this.schoolId = schoolId; + this.countryCode = countryCode; + this.schoolName = schoolName; + this.town = town; + this.postalCode = postalCode; + this.excluded = excluded; this.closed = closed; + this.dataSource = dataSource; } /** - * Gets the urn. - * - * @return the urn + * Gets the school ID. + * + * @return the school ID */ - public String getUrn() { - return urn; + public String getSchoolId() { + return schoolId; } /** - * Sets the urn. - * - * @param urn - * the urn to set + * Sets the school ID. + * + * @param schoolId + * the school ID to set */ - public void setUrn(final String urn) { - this.urn = urn; + public void setSchoolId(final String schoolId) { + this.schoolId = schoolId; } /** - * Gets the name. - * - * @return the name + * Gets the country code. + * + * @return the country code */ - public String getName() { - return name; + public String getCountryCode() { + return countryCode; } /** - * Sets the name. - * - * @param name - * the name to set + * Sets the country code. + * + * @param countryCode + * the country code to set */ - public void setName(final String name) { - this.name = name; + public void setCountryCode(final String countryCode) { + this.countryCode = countryCode; } /** - * Gets the postcode. - * - * @return the postcode + * Gets the school name. + * + * @return the school name */ - public String getPostcode() { - return postcode; + public String getSchoolName() { + return schoolName; } /** - * Sets the postcode. - * - * @param postcode - * the postcode to set + * Sets the school name. + * + * @param schoolName + * the school name to set */ - public void setPostcode(final String postcode) { - this.postcode = postcode; + public void setSchoolName(final String schoolName) { + this.schoolName = schoolName; } + /** + * Gets the town. + * + * @return the town + */ + public String getTown() { + return town; + } + + /** + * Sets the town. + * + * @param town + * the town to set + */ + public void setTown(final String town) { + this.town = town; + } + + /** + * Gets the postal code. + * + * @return the postal code + */ + public String getPostalCode() { + return postalCode; + } + + /** + * Sets the postal code. + * + * @param postalCode + * the postal code to set + */ + public void setPostalCode(final String postalCode) { + this.postalCode = postalCode; + } + + /** + * Gets the excluded status. + * + * @return whether the school is excluded when searching for schools by name + */ + public Boolean getExcluded() { + return excluded; + } + + /** + * Sets the excluded status. + * + * @param excluded + * whether the school should be excluded when searching for schools by name + */ + public void setExcluded(final Boolean excluded) { + this.excluded = excluded; + } /** * Gets the closed status. * * @return whether the school is closed */ - public Boolean isClosed() { + public Boolean getClosed() { return closed; } @@ -146,19 +215,19 @@ public void setClosed(final Boolean closed) { } /** - * Gets the verifiedSchool. + * Gets the data source for the school information. * - * @return the verifiedSchool + * @return the data source */ public SchoolDataSource getDataSource() { return dataSource; } /** - * Sets the dataSource. + * Sets the data source for the school information. * * @param dataSource - * the dataSource to set + * the data source to set */ public void setDataSource(final SchoolDataSource dataSource) { this.dataSource = dataSource; @@ -168,7 +237,7 @@ public void setDataSource(final SchoolDataSource dataSource) { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((urn == null) ? 0 : urn.hashCode()); + result = prime * result + ((schoolId == null) ? 0 : schoolId.hashCode()); return result; } @@ -184,11 +253,11 @@ public boolean equals(final Object obj) { return false; } School other = (School) obj; - if (urn == null) { - if (other.urn != null) { + if (schoolId == null) { + if (other.schoolId != null) { return false; } - } else if (!urn.equals(other.urn)) { + } else if (!schoolId.equals(other.schoolId)) { return false; } return true; @@ -196,6 +265,6 @@ public boolean equals(final Object obj) { @Override public String toString() { - return "School [urn=" + urn + ", name=" + name + ", postcode=" + postcode + "]"; + return "School [id=" + schoolId + ", name=" + schoolName + ", postcode=" + postalCode + "]"; } } diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/api/AdminFacade.java b/src/main/java/uk/ac/cam/cl/dtg/segue/api/AdminFacade.java index 9563df2052..8074a5e038 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/api/AdminFacade.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/api/AdminFacade.java @@ -806,8 +806,8 @@ public Response getContentProblems(@Context final HttpServletRequest request, * - if searching by school other field. * @param postcode * - if searching by postcode. - * @param schoolURN - * - if searching by school by the URN. + * @param schoolId + * - if searching for school by ID. * @param emailVerificationStatus * - if searching by email verification status * @return a userDTO or a segue error response @@ -822,7 +822,7 @@ public Response findUsers(@Context final HttpServletRequest httpServletRequest, @QueryParam("schoolOther") @Nullable final String schoolOther, @QueryParam("postcode") @Nullable final String postcode, @QueryParam("postcodeRadius") @Nullable final String postcodeRadius, - @QueryParam("schoolURN") @Nullable final String schoolURN, + @QueryParam("schoolId") @Nullable final String schoolId, @QueryParam("emailVerificationStatus") @Nullable final EmailVerificationStatus emailVerificationStatus) { RegisteredUserDTO currentUser; @@ -839,7 +839,7 @@ public Response findUsers(@Context final HttpServletRequest httpServletRequest, && (null == familyName || familyName.isEmpty()) && (null == schoolOther || schoolOther.isEmpty()) && (null == email || email.isEmpty()) - && (null == schoolURN || schoolURN.isEmpty()) + && (null == schoolId || schoolId.isEmpty()) && (null == postcode || postcode.isEmpty())) { return new SegueErrorResponse(Status.FORBIDDEN, "You do not have permission to do wildcard searches.") .toResponse(); @@ -885,8 +885,8 @@ public Response findUsers(@Context final HttpServletRequest httpServletRequest, userPrototype.setSchoolOther(schoolOther); } - if (null != schoolURN) { - userPrototype.setSchoolId(schoolURN); + if (null != schoolId) { + userPrototype.setSchoolId(schoolId); } if (null != emailVerificationStatus) { @@ -915,7 +915,7 @@ public Response findUsers(@Context final HttpServletRequest httpServletRequest, if (userDTO.getSchoolId() != null) { School school = this.schoolReader.findSchoolById(userDTO.getSchoolId()); if (school != null) { - String schoolPostCode = school.getPostcode(); + String schoolPostCode = school.getPostalCode(); if (null == schoolPostCode || schoolPostCode.isEmpty()) { continue; } diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/api/Constants.java b/src/main/java/uk/ac/cam/cl/dtg/segue/api/Constants.java index 5a6e27249b..8e746e11a7 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/api/Constants.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/api/Constants.java @@ -509,18 +509,15 @@ public enum EventFilterOption { public static final String ID_SEPARATOR = "|"; public static final String ESCAPED_ID_SEPARATOR = "\\" + ID_SEPARATOR; - // School List loading - raw data - public static final String SCHOOL_URN_FIELDNAME = "URN"; - public static final String SCHOOL_ESTABLISHMENT_NAME_FIELDNAME = "EstablishmentName"; - public static final String SCHOOL_POSTCODE_FIELDNAME = "Postcode"; - public static final String SCHOOL_DATA_SOURCE_FIELDNAME = "DataSource"; - public static final String SCHOOL_CLOSED_FIELDNAME = "Closed"; - - // School List loading POJO fields - public static final String SCHOOL_URN_FIELDNAME_POJO = "urn"; - public static final String SCHOOL_ESTABLISHMENT_NAME_FIELDNAME_POJO = "name"; - public static final String SCHOOL_POSTCODE_FIELDNAME_POJO = "postcode"; - public static final String SCHOOL_CLOSED_FIELDNAME_POJO = "closed"; + // School List loading + public static final String SCHOOL_ID_FIELDNAME = "schoolId"; + public static final String SCHOOL_COUNTRY_CODE_FIELDNAME = "countryCode"; + public static final String SCHOOL_NAME_FIELDNAME = "schoolName"; + public static final String SCHOOL_TOWN_FIELDNAME = "town"; + public static final String SCHOOL_POSTCODE_FIELDNAME = "postalCode"; + public static final String SCHOOL_EXCLUDED_FIELDNAME = "excluded"; + public static final String SCHOOL_CLOSED_FIELDNAME = "closed"; + public static final String SCHOOL_DATA_SOURCE_FIELDNAME = "dataSource"; // User School Reporting diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/api/SchoolLookupServiceFacade.java b/src/main/java/uk/ac/cam/cl/dtg/segue/api/SchoolLookupServiceFacade.java index 30167c14e7..99b14a700f 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/api/SchoolLookupServiceFacade.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/api/SchoolLookupServiceFacade.java @@ -40,7 +40,7 @@ import jakarta.ws.rs.core.Response.ResponseBuilder; import jakarta.ws.rs.core.Response.Status; import java.io.IOException; -import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -70,8 +70,8 @@ public SchoolLookupServiceFacade(final SchoolListReader schoolListReader) { * * @param request * - for caching purposes. - * @param schoolURN - * - find by urn. + * @param schoolId + * - find by school ID. * @param searchQuery * - query to search fields against. * @param limit @@ -84,10 +84,11 @@ public SchoolLookupServiceFacade(final SchoolListReader schoolListReader) { @GZIP @Operation(summary = "List all schools matching provided criteria.") public Response schoolSearch(@Context final Request request, @QueryParam("query") final String searchQuery, - @QueryParam("urn") final String schoolURN, @QueryParam("limit") final Integer limit) { + @QueryParam("countryCode") final String countryCode, @QueryParam("schoolId") final String schoolId, + @QueryParam("limit") final Integer limit) { - if ((null == searchQuery || searchQuery.isEmpty()) && (null == schoolURN || schoolURN.isEmpty())) { - return new SegueErrorResponse(Status.BAD_REQUEST, "You must provide a search query or school URN") + if ((null == searchQuery || searchQuery.isEmpty()) && (null == schoolId || schoolId.isEmpty())) { + return new SegueErrorResponse(Status.BAD_REQUEST, "You must provide a search query or school ID") .toResponse(); } @@ -109,10 +110,10 @@ public Response schoolSearch(@Context final Request request, @QueryParam("query" List list; try { - if (schoolURN != null && !schoolURN.isEmpty()) { - list = Arrays.asList(schoolListReader.findSchoolById(schoolURN)); + if (schoolId != null && !schoolId.isEmpty()) { + list = Collections.singletonList(schoolListReader.findSchoolById(schoolId)); } else { - list = schoolListReader.findSchoolByNameOrPostCode(searchQuery, limit); + list = schoolListReader.findSchoolByNameOrPostCode(searchQuery, countryCode, limit); } } catch (UnableToIndexSchoolsException | SegueSearchException | IOException e) { @@ -120,7 +121,7 @@ public Response schoolSearch(@Context final Request request, @QueryParam("query" log.error(message, e); return new SegueErrorResponse(Status.INTERNAL_SERVER_ERROR, message, e).toResponse(); } catch (NumberFormatException e) { - return new SegueErrorResponse(Status.BAD_REQUEST, "The school urn provided is invalid.").toResponse(); + return new SegueErrorResponse(Status.BAD_REQUEST, "The school ID provided is invalid.").toResponse(); } return Response.ok(list).tag(etag).cacheControl(cc).build(); diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/api/UsersFacade.java b/src/main/java/uk/ac/cam/cl/dtg/segue/api/UsersFacade.java index 66e370d045..32f57e8f3a 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/api/UsersFacade.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/api/UsersFacade.java @@ -730,7 +730,7 @@ public Response getUserIdToSchoolMap(@Context final HttpServletRequest httpServl if (null != school) { builder.put(user.getId().toString(), school); } else { - // The school once existed in the list but no longer does. Set the name to be the URN: + // The school once existed in the list but no longer does. Set the name to be the ID: builder.put(user.getId().toString(), ImmutableMap.of("name", user.getSchoolId())); } } else if (user.getSchoolOther() != null && !user.getSchoolOther().isEmpty()) { diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/dao/schools/SchoolListReader.java b/src/main/java/uk/ac/cam/cl/dtg/segue/dao/schools/SchoolListReader.java index 4b09db0ae1..52ae0fa880 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/dao/schools/SchoolListReader.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/dao/schools/SchoolListReader.java @@ -25,13 +25,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.ac.cam.cl.dtg.isaac.dos.users.School; +import uk.ac.cam.cl.dtg.segue.search.BooleanInstruction; import uk.ac.cam.cl.dtg.segue.search.ISearchProvider; +import uk.ac.cam.cl.dtg.segue.search.MatchInstruction; import uk.ac.cam.cl.dtg.segue.search.SegueSearchException; import jakarta.annotation.Nullable; import java.io.IOException; import java.util.List; -import java.util.Map; import static uk.ac.cam.cl.dtg.segue.api.Constants.*; @@ -75,17 +76,20 @@ public SchoolListReader(final ISearchProvider searchProvider) { } /** - * findSchoolByNameOrPostCode. + * Search for schools by ID, name or postcode. Filterable by country. Excludes schools marked as closed or excluded. * * @param searchQuery - * - school to search for - either name or postcode. + * - school to search for - either ID, name or postcode. + * @param countryCode + * - country code to filter by. * @param limit * - the number of results to return. * @return list of schools matching the criteria or an empty list. * @throws UnableToIndexSchoolsException * - if there is an error access the index of schools. */ - public List findSchoolByNameOrPostCode(final String searchQuery, @Nullable final Integer limit) throws UnableToIndexSchoolsException, SegueSearchException { + public List findSchoolByNameOrPostCode(final String searchQuery, @Nullable final String countryCode, + @Nullable final Integer limit) throws UnableToIndexSchoolsException, SegueSearchException { if (!this.ensureSchoolList()) { log.error("Unable to ensure school search cache."); throw new UnableToIndexSchoolsException("unable to ensure the cache has been populated"); @@ -93,10 +97,22 @@ public List findSchoolByNameOrPostCode(final String searchQuery, @Nullab Integer queryLimit = limit == null ? DEFAULT_RESULTS_LIMIT : limit; - List schoolSearchResults = searchProvider.fuzzySearch(SCHOOLS_INDEX_BASE, SCHOOLS_INDEX_TYPE.SCHOOL_SEARCH.toString(), - searchQuery, 0, queryLimit, Map.of(SCHOOL_CLOSED_FIELDNAME_POJO, List.of("false")), null, SCHOOL_URN_FIELDNAME_POJO, - SCHOOL_ESTABLISHMENT_NAME_FIELDNAME_POJO, SCHOOL_POSTCODE_FIELDNAME_POJO) - .getResults(); + BooleanInstruction matchInstruction = new BooleanInstruction(); + // Exclude excluded/closed schools + matchInstruction.must(new MatchInstruction(SCHOOL_EXCLUDED_FIELDNAME, "false", null, false)); + matchInstruction.must(new MatchInstruction(SCHOOL_CLOSED_FIELDNAME, "false", null, false)); + // Compulsorily match country code, if provided. Needs to be a raw field since GB- country codes contain hyphens. + if (null != countryCode && !countryCode.isEmpty()) { + matchInstruction.must(new MatchInstruction(SCHOOL_COUNTRY_CODE_FIELDNAME + "." + UNPROCESSED_SEARCH_FIELD_SUFFIX, + countryCode, null, false)); + } + // Attempt to match on school ID, name & postcode + matchInstruction.should(new MatchInstruction(SCHOOL_ID_FIELDNAME, searchQuery, null, true)); + matchInstruction.should(new MatchInstruction(SCHOOL_NAME_FIELDNAME, searchQuery, null, true)); + matchInstruction.should(new MatchInstruction(SCHOOL_POSTCODE_FIELDNAME, searchQuery, null, true)); + + List schoolSearchResults = searchProvider.nestedMatchSearch(SCHOOLS_INDEX_BASE, + SCHOOLS_INDEX_TYPE.SCHOOL_SEARCH.toString(), 0, queryLimit, matchInstruction, null, null).getResults(); List resultList = Lists.newArrayList(); for (String schoolString : schoolSearchResults) { @@ -114,7 +130,7 @@ public List findSchoolByNameOrPostCode(final String searchQuery, @Nullab /** * Find school by Id. * - * @param schoolURN + * @param schoolId * - to search for. * @return school. * @throws UnableToIndexSchoolsException @@ -126,7 +142,7 @@ public List findSchoolByNameOrPostCode(final String searchQuery, @Nullab * @throws JsonParseException * - if the school data is malformed */ - public School findSchoolById(final String schoolURN) throws UnableToIndexSchoolsException, JsonParseException, + public School findSchoolById(final String schoolId) throws UnableToIndexSchoolsException, JsonParseException, JsonMappingException, IOException, SegueSearchException { if (!this.ensureSchoolList()) { @@ -137,15 +153,14 @@ public School findSchoolById(final String schoolURN) throws UnableToIndexSchools List matchingSchoolList; matchingSchoolList = searchProvider.findByExactMatch(SCHOOLS_INDEX_BASE, SCHOOLS_INDEX_TYPE.SCHOOL_SEARCH.toString(), - SCHOOL_URN_FIELDNAME.toLowerCase() + "." + UNPROCESSED_SEARCH_FIELD_SUFFIX, - schoolURN, 0, DEFAULT_RESULTS_LIMIT, null).getResults(); + SCHOOL_ID_FIELDNAME, schoolId, 0, DEFAULT_RESULTS_LIMIT, null).getResults(); if (matchingSchoolList.isEmpty()) { return null; } if (matchingSchoolList.size() > 1) { - log.error("Error while looking up school up by id! More than one match for '{}' results: {}", schoolURN, matchingSchoolList); + log.error("Error while looking up school up by id! More than one match for '{}' results: {}", schoolId, matchingSchoolList); } return mapper.readValue(matchingSchoolList.getFirst(), School.class); diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/etl/ElasticSearchIndexer.java b/src/main/java/uk/ac/cam/cl/dtg/segue/etl/ElasticSearchIndexer.java index c0c39f4168..7c88a1d4a8 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/etl/ElasticSearchIndexer.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/etl/ElasticSearchIndexer.java @@ -61,7 +61,7 @@ public class ElasticSearchIndexer extends ElasticSearchProvider { public ElasticSearchIndexer(final ElasticsearchClient searchClient) { super(searchClient); rawFieldsListByType.put("content", Lists.newArrayList("id", "title", "subtitle")); - rawFieldsListByType.put("school", Lists.newArrayList("urn")); + rawFieldsListByType.put("school", Lists.newArrayList("countryCode")); nestedFieldsByType.put("content", Lists.newArrayList("audience")); } diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/etl/SchoolIndexer.java b/src/main/java/uk/ac/cam/cl/dtg/segue/etl/SchoolIndexer.java index d21c648ea1..4be7060959 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/etl/SchoolIndexer.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/etl/SchoolIndexer.java @@ -65,7 +65,7 @@ synchronized void indexSchoolsWithSearchProvider() throws UnableToIndexSchoolsEx for (School school : schoolList) { try { - indexList.add(immutableEntry(school.getUrn(), objectMapper.writeValueAsString(school))); + indexList.add(immutableEntry(school.getSchoolId(), objectMapper.writeValueAsString(school))); } catch (JsonProcessingException e) { log.error("Unable to serialize the school object into json.", e); } @@ -121,22 +121,25 @@ private synchronized List loadAndBuildSchoolList() throws UnableToIndexS } // We expect the columns to have the following names/structure and be UTF-8 encoded: - // URN | EstablishmentName | Postcode | Closed | DataSource + // schoolId | countryCode | schoolName | town | postalCode | excluded | closed | dataSource String[] schoolArray; while ((schoolArray = reader.readNext()) != null) { try { School.SchoolDataSource source = School.SchoolDataSource .valueOf(schoolArray[fieldNameMapping.get(Constants.SCHOOL_DATA_SOURCE_FIELDNAME)]); - School schoolToSave = new School(schoolArray[fieldNameMapping.get(Constants.SCHOOL_URN_FIELDNAME)], - schoolArray[fieldNameMapping.get(Constants.SCHOOL_ESTABLISHMENT_NAME_FIELDNAME)], + School schoolToSave = new School(schoolArray[fieldNameMapping.get(Constants.SCHOOL_ID_FIELDNAME)], + schoolArray[fieldNameMapping.get(Constants.SCHOOL_COUNTRY_CODE_FIELDNAME)], + schoolArray[fieldNameMapping.get(Constants.SCHOOL_NAME_FIELDNAME)], + schoolArray[fieldNameMapping.get(Constants.SCHOOL_TOWN_FIELDNAME)], schoolArray[fieldNameMapping.get(Constants.SCHOOL_POSTCODE_FIELDNAME)], - // CSV file contains string "t" and "f" values to denote true and false, but need a boolean: - "t".equals(schoolArray[fieldNameMapping.get(Constants.SCHOOL_CLOSED_FIELDNAME)]), + // CSV file contains string "true" and "false" values to denote true and false, but need a boolean: + "true".equals(schoolArray[fieldNameMapping.get(Constants.SCHOOL_EXCLUDED_FIELDNAME)]), + "true".equals(schoolArray[fieldNameMapping.get(Constants.SCHOOL_CLOSED_FIELDNAME)]), source); - if (null == schoolToSave.getPostcode() || schoolToSave.getPostcode().isEmpty()) { - log.warn("School with missing postcode! URN: {}", schoolToSave.getUrn()); + if (null == schoolToSave.getPostalCode() || schoolToSave.getPostalCode().isEmpty()) { + log.warn("School with missing postcode! School ID: {}", schoolToSave.getSchoolId()); } schools.add(schoolToSave); diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/search/ElasticSearchProvider.java b/src/main/java/uk/ac/cam/cl/dtg/segue/search/ElasticSearchProvider.java index 41dfc70dda..a91f5cf4b3 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/search/ElasticSearchProvider.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/search/ElasticSearchProvider.java @@ -217,76 +217,6 @@ public ResultsWrapper nestedMatchSearch(final String indexBase, final St return this.executeBasicQuery(indexBase, indexType, query, startIndex, limit, sortOrder); } - @Override - @Deprecated - public ResultsWrapper fuzzySearch(final String indexBase, final String indexType, final String searchString, - final Integer startIndex, final Integer limit, - @Nullable final Map> fieldsThatMustMatch, - @Nullable final Map filterInstructions, - final String... fields) throws SegueSearchException { - if (null == indexBase || null == indexType || null == searchString || null == fields) { - log.warn("A required field is missing. Unable to execute search."); - return null; - } - - BoolQuery.Builder masterQuery; - if (null != fieldsThatMustMatch) { - masterQuery = new BoolQuery.Builder().must(this.generateBoolMatchQuery(this.convertToBoolMap(fieldsThatMustMatch))._toQuery()); - } else { - masterQuery = new BoolQuery.Builder(); - } - - BoolQuery.Builder query = new BoolQuery.Builder(); - Set boostFields = ImmutableSet.of("id", "title", "tags"); - - List searchTerms = Lists.newArrayList(); - searchTerms.addAll(Arrays.asList(searchString.split(" "))); - if (searchTerms.size() > 1) { - searchTerms.add(searchString); - } - - for (String f : fields) { - float boost = boostFields.contains(f) ? 2f : 1f; - - for (String searchTerm : searchTerms) { - Query initialFuzzySearch = MatchQuery.of(m -> m - .field(f) - .query(searchTerm) - .fuzziness("AUTO") - .prefixLength(0) - .boost(boost) - )._toQuery(); - query.should(initialFuzzySearch); - - Query regexSearch = WildcardQuery.of(r -> r - .field(f) - .value("*" + searchTerm + "*") - .boost(boost) - )._toQuery(); - query.should(regexSearch); - } - } - - // this query is just a bit smarter than the regex search above. - Query multiMatchPrefixQuery = MultiMatchQuery.of(mm -> mm - .query(searchString) - .fields(Arrays.asList(fields)) - .type(TextQueryType.PhrasePrefix) - .prefixLength(2) - .boost(2.0f) - )._toQuery(); - query.should(multiMatchPrefixQuery); - - masterQuery.must(query.build()._toQuery()); - - if (filterInstructions != null) { - masterQuery.filter(generateFilterQuery(filterInstructions)); - } - - Query finalQuery = masterQuery.build()._toQuery(); - return this.executeBasicQuery(indexBase, indexType, finalQuery, startIndex, limit); - } - @Override public ResultsWrapper termSearch(final String indexBase, final String indexType, final String searchTerm, final String field, final int startIndex, final int limit, diff --git a/src/main/java/uk/ac/cam/cl/dtg/segue/search/ISearchProvider.java b/src/main/java/uk/ac/cam/cl/dtg/segue/search/ISearchProvider.java index 68c13a9d28..14c587c051 100644 --- a/src/main/java/uk/ac/cam/cl/dtg/segue/search/ISearchProvider.java +++ b/src/main/java/uk/ac/cam/cl/dtg/segue/search/ISearchProvider.java @@ -77,38 +77,6 @@ ResultsWrapper matchSearch( @Nullable final Map filterInstructions ) throws SegueSearchException; - /** - * Executes a fuzzy search on an array of fields and will consider the fieldsThatMustMatchMap. - * - * This method should prioritise exact prefix matches and then fill it with fuzzy ones. - * - * @param indexBase - * - the base string for the name of the index - * @param indexType - * - the name of the type of document being searched for - * @param searchString - * - the string to use for fuzzy matching - * @param startIndex - * - e.g. 0 for the first set of results - * @param limit - * - the maximum number of results to return -1 will attempt to return all results. - * @param fieldsThatMustMatch - * - Map of Must match field -> value - * @param filterInstructions - * - post search filter instructions e.g. remove content of a certain type. - * @param fields - * - array (var args) of fields to search using the searchString - * @return results - * @deprecated in favour of {@code BooleanInstruction}-based searches. - */ - @Deprecated - ResultsWrapper fuzzySearch( - final String indexBase, final String indexType, final String searchString, - final Integer startIndex, final Integer limit, final Map> fieldsThatMustMatch, - @Nullable final Map filterInstructions, - final String... fields - ) throws SegueSearchException; - ResultsWrapper nestedMatchSearch( final String indexBase, final String indexType, final Integer startIndex, final Integer limit, @NotNull final BooleanInstruction matchInstruction, @Nullable Long randomSeed,