From 9e62d5f317ca26c03808ffa6c7cb27f67e066cde Mon Sep 17 00:00:00 2001 From: James McLaughlin Date: Wed, 1 Nov 2023 00:25:07 +0000 Subject: [PATCH 1/3] implement AND/OR for dynamic query parameters (#170) --- .../controller/api/v2/V2ClassController.java | 15 ++-- .../controller/api/v2/V2EntityController.java | 15 ++-- .../api/v2/V2IndividualController.java | 15 ++-- .../api/v2/V2OntologyController.java | 8 ++- .../api/v2/V2PropertyController.java | 15 ++-- .../api/v2/helpers/DynamicQueryHelper.java | 9 ++- .../ols/repository/solr/OlsSolrClient.java | 2 + .../ols/repository/solr/OlsSolrQuery.java | 32 ++++++--- .../repository/v1/V1IndividualRepository.java | 59 ++++++++-------- .../repository/v1/V1OntologyRepository.java | 8 ++- .../repository/v1/V1PropertyRepository.java | 69 +++++++++--------- .../ols/repository/v1/V1TermRepository.java | 70 +++++++++---------- .../ols/repository/v2/V2ClassRepository.java | 18 ++--- .../ols/repository/v2/V2EntityRepository.java | 18 ++--- .../repository/v2/V2IndividualRepository.java | 24 ++++--- .../repository/v2/V2OntologyRepository.java | 11 +-- .../repository/v2/V2PropertyRepository.java | 18 ++--- .../v2/helpers/V2DynamicFilterParser.java | 11 +-- 18 files changed, 233 insertions(+), 184 deletions(-) diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2ClassController.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2ClassController.java index 6c3d017c3..d8b8b4fde 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2ClassController.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2ClassController.java @@ -14,6 +14,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -29,7 +30,9 @@ import javax.validation.constraints.NotNull; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; @Controller @@ -48,12 +51,12 @@ public HttpEntity> getClasses( @RequestParam(value = "boostFields", required = false) String boostFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam MultiValueMap searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( @@ -74,12 +77,12 @@ public HttpEntity> getClasses( @RequestParam(value = "boostFields", required = false) String boostFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam MultiValueMap searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2EntityController.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2EntityController.java index d814dbc73..6c760ae8e 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2EntityController.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2EntityController.java @@ -9,6 +9,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -22,7 +23,9 @@ import javax.validation.constraints.NotNull; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; @Controller @@ -42,12 +45,12 @@ public HttpEntity> getEntities( @RequestParam(value = "facetFields", required = false) String facetFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam MultiValueMap searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( @@ -68,12 +71,12 @@ public HttpEntity> getTerms( @RequestParam(value = "facetFields", required = false) String facetFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam MultiValueMap searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2IndividualController.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2IndividualController.java index 94a677526..bff23a360 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2IndividualController.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2IndividualController.java @@ -10,6 +10,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -23,7 +24,9 @@ import javax.validation.constraints.NotNull; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; @Controller @@ -42,12 +45,12 @@ public HttpEntity> getIndividuals( @RequestParam(value = "boostFields", required = false) String boostFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam MultiValueMap searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( @@ -67,12 +70,12 @@ public HttpEntity> getIndividuals( @RequestParam(value = "boostFields", required = false) String boostFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam MultiValueMap searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2OntologyController.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2OntologyController.java index e222820e2..6a9c8501e 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2OntologyController.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2OntologyController.java @@ -24,7 +24,9 @@ import uk.ac.ebi.spot.ols.repository.v2.V2OntologyRepository; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; @Controller @@ -47,12 +49,12 @@ public HttpEntity> getOntologies( @RequestParam(value = "boostFields", required = false) String boostFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam Map> searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2PropertyController.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2PropertyController.java index 48b050d3a..ee847f3cd 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2PropertyController.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/V2PropertyController.java @@ -9,6 +9,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriUtils; import uk.ac.ebi.spot.ols.controller.api.v2.helpers.DynamicQueryHelper; @@ -19,7 +20,9 @@ import javax.validation.constraints.NotNull; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; @Controller @@ -38,12 +41,12 @@ public HttpEntity> getProperties( @RequestParam(value = "boostFields", required = false) String boostFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam Map> searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( @@ -63,12 +66,12 @@ public HttpEntity> getProperties( @RequestParam(value = "boostFields", required = false) String boostFields, @RequestParam(value = "exactMatch", required = false, defaultValue = "false") boolean exactMatch, @RequestParam(value = "includeObsoleteEntities", required = false, defaultValue = "false") boolean includeObsoleteEntities, - @RequestParam Map searchProperties + @RequestParam MultiValueMap searchProperties ) throws ResourceNotFoundException, IOException { - Map properties = new HashMap<>(); + Map> properties = new HashMap<>(); if(!includeObsoleteEntities) - properties.put("isObsolete", "false"); + properties.put("isObsolete", List.of("false")); properties.putAll(searchProperties); return new ResponseEntity<>( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/helpers/DynamicQueryHelper.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/helpers/DynamicQueryHelper.java index a9a0c5e60..80b1ade32 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/helpers/DynamicQueryHelper.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/v2/helpers/DynamicQueryHelper.java @@ -4,17 +4,16 @@ import java.util.HashMap; import java.util.Map; +import java.util.Collection; public class DynamicQueryHelper { - public static Map filterProperties(Map properties) { + public static Map> filterProperties(Map> properties) { - Map newProps = new HashMap<>(); + Map> newProps = new HashMap<>(); for(String k : properties.keySet()) { - String value = properties.get(k); - k = UriUtils.decode(k, "UTF-8"); if(k.equals("lang") || k.equals("search") || k.equals("searchFields") @@ -22,7 +21,7 @@ public static Map filterProperties(Map properties) || k.equals("includeObsoleteEntities")) continue; - newProps.put(k, value); + newProps.put(k, properties.get(k)); } return newProps; diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrClient.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrClient.java index d60cc9da9..065b5d8c5 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrClient.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrClient.java @@ -22,6 +22,7 @@ import javax.validation.constraints.NotNull; import java.io.IOException; +import java.net.URLDecoder; import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; @@ -115,6 +116,7 @@ public QueryResponse runSolrQuery(SolrQuery query, Pageable pageable) { } System.out.println("solr query: " + query.toQueryString()); + System.out.println("solr query urldecoded: " + URLDecoder.decode(query.toQueryString())); System.out.println("solr host: " + host); org.apache.solr.client.solrj.SolrClient mySolrClient = new HttpSolrClient.Builder(host + "/solr/ols4_entities").build(); diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java index ed33befb7..a3cab7013 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java @@ -1,6 +1,7 @@ package uk.ac.ebi.spot.ols.repository.solr; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.apache.solr.client.solrj.SolrQuery; @@ -43,8 +44,8 @@ public void addFacetField(String propertyName) { this.facetFields.add(propertyName); } - public void addFilter(String propertyName, String propertyValue, SearchType searchType) { - this.filters.add(new Filter(propertyName, propertyValue, searchType)); + public void addFilter(String propertyName, Collection propertyValues, SearchType searchType) { + this.filters.add(new Filter(propertyName, propertyValues, searchType)); } public SolrQuery constructQuery() { @@ -98,9 +99,24 @@ public SolrQuery constructQuery() { } for(Filter f : filters) { - query.addFilterQuery( - ClientUtils.escapeQueryChars(getSolrPropertyName(f.propertyName, f.searchType)) - + ":\"" + ClientUtils.escapeQueryChars(getSolrPropertyValue(f.propertyValue, exactMatch ? SearchType.WHOLE_FIELD : f.searchType)) + "\""); + + StringBuilder fq = new StringBuilder(); + fq.append( ClientUtils.escapeQueryChars(getSolrPropertyName(f.propertyName, f.searchType)) ); + fq.append(":("); + + int n = 0; + + for(String value : f.propertyValues) { + if(n ++ > 0) { + fq.append(" OR "); + } + fq.append("\""); + fq.append(ClientUtils.escapeQueryChars(getSolrPropertyValue(value, exactMatch ? SearchType.WHOLE_FIELD : f.searchType))); + fq.append("\""); + } + fq.append(")"); + + query.addFilterQuery(fq.toString()); } if(facetFields.size() > 0) { @@ -113,12 +129,12 @@ public SolrQuery constructQuery() { private class Filter { String propertyName; - String propertyValue; + Collection propertyValues; // all values to search for ("OR") SearchType searchType; - public Filter(String propertyName, String propertyValue, SearchType searchType) { + public Filter(String propertyName, Collection propertyValues, SearchType searchType) { this.propertyName = propertyName; - this.propertyValue = propertyValue; + this.propertyValues = propertyValues; this.searchType = searchType; } } diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1IndividualRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1IndividualRepository.java index 0ad307b29..fe883ebbd 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1IndividualRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1IndividualRepository.java @@ -1,6 +1,7 @@ package uk.ac.ebi.spot.ols.repository.v1; import java.util.Arrays; +import java.util.List; import java.util.Map; import com.google.gson.JsonElement; @@ -55,9 +56,9 @@ public Page getAllTypes(String ontologyId, String iri, String lang, Page public V1Individual findByOntologyAndIri(String ontologyId, String iri, String lang) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return V1IndividualMapper.mapIndividual(solrClient.getFirst(query), lang); } @@ -67,8 +68,8 @@ public V1Individual findByOntologyAndIri(String ontologyId, String iri, String l public OlsFacetedResultsPage findAllByOntology(String ontologyId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1IndividualMapper.mapIndividual(result, lang)); @@ -78,9 +79,9 @@ public OlsFacetedResultsPage findAllByOntology(String ontologyId, public V1Individual findByOntologyAndShortForm(String ontologyId, String lang, String shortForm) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); return V1IndividualMapper.mapIndividual(solrClient.getFirst(query), lang); } @@ -89,9 +90,9 @@ public V1Individual findByOntologyAndShortForm(String ontologyId, String lang, S public V1Individual findByOntologyAndOboId(String ontologyId, String lang, String oboId) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("oboId", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("oboId", List.of(oboId), SearchType.WHOLE_FIELD); return V1IndividualMapper.mapIndividual(solrClient.getFirst(query), lang); @@ -102,7 +103,7 @@ public V1Individual findByOntologyAndOboId(String ontologyId, String lang, Strin public OlsFacetedResultsPage findAll(String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); @@ -114,8 +115,8 @@ public OlsFacetedResultsPage findAll(String lang, Pageable pageabl public OlsFacetedResultsPage findAllByIsDefiningOntology(String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); @@ -129,8 +130,8 @@ public OlsFacetedResultsPage findAllByIsDefiningOntology(String la public OlsFacetedResultsPage findAllByIri(String iri, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); @@ -143,9 +144,9 @@ public OlsFacetedResultsPage findAllByIri(String iri, String lang, public OlsFacetedResultsPage findAllByIriAndIsDefiningOntology(String iri, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); @@ -158,8 +159,8 @@ public OlsFacetedResultsPage findAllByIriAndIsDefiningOntology(Str public OlsFacetedResultsPage findAllByShortForm(String shortForm, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); @@ -174,9 +175,9 @@ public OlsFacetedResultsPage findAllByShortForm(String shortForm, public OlsFacetedResultsPage findAllByShortFormAndIsDefiningOntology(String shortForm, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); @@ -188,8 +189,8 @@ public OlsFacetedResultsPage findAllByShortFormAndIsDefiningOntolo public OlsFacetedResultsPage findAllByOboId(String oboId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("oboId", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("oboId", List.of(oboId), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); @@ -202,9 +203,9 @@ public OlsFacetedResultsPage findAllByOboId(String oboId, String l public OlsFacetedResultsPage findAllByOboIdAndIsDefiningOntology(String oboId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); - query.addFilter("oboId", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); + query.addFilter("oboId", List.of(oboId), SearchType.WHOLE_FIELD); OlsFacetedResultsPage entities = solrClient.searchSolrPaginated(query, pageable); diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1OntologyRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1OntologyRepository.java index cce272305..61fa1c249 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1OntologyRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1OntologyRepository.java @@ -12,6 +12,8 @@ import uk.ac.ebi.spot.ols.repository.Validation; import uk.ac.ebi.spot.ols.repository.v1.mappers.V1OntologyMapper; +import java.util.List; + @Component public class V1OntologyRepository { @@ -24,8 +26,8 @@ public V1Ontology get(String ontologyId, String lang) { Validation.validateOntologyId(ontologyId); OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "ontology", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("ontology"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); return V1OntologyMapper.mapOntology(solrClient.getFirst(query), lang); } @@ -35,7 +37,7 @@ public Page getAll(String lang, Pageable pageable) { Validation.validateLang(lang); OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "ontology", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("ontology"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1OntologyMapper.mapOntology(result, lang)); diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1PropertyRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1PropertyRepository.java index bf37330cc..7078b7daf 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1PropertyRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1PropertyRepository.java @@ -1,6 +1,7 @@ package uk.ac.ebi.spot.ols.repository.v1; import java.util.Arrays; +import java.util.List; import java.util.Map; import org.springframework.data.domain.Page; @@ -49,17 +50,17 @@ public Page getAncestors(String ontologyId, String iri, String lang, public V1Property findByOntologyAndIri(String ontologyId, String iri, String lang) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return V1PropertyMapper.mapProperty(solrClient.getFirst(query), lang); } public Page findAllByOntology(String ontologyId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -68,9 +69,9 @@ public Page findAllByOntology(String ontologyId, String lang, Pageab public V1Property findByOntologyAndShortForm(String ontologyId, String shortForm, String lang) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); return V1PropertyMapper.mapProperty(solrClient.getFirst(query), lang); @@ -79,9 +80,9 @@ public V1Property findByOntologyAndShortForm(String ontologyId, String shortForm public V1Property findByOntologyAndOboId(String ontologyId, String oboId, String lang) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("oboId", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("oboId", List.of(oboId), SearchType.WHOLE_FIELD); return V1PropertyMapper.mapProperty(solrClient.getFirst(query), lang); @@ -90,13 +91,13 @@ public V1Property findByOntologyAndOboId(String ontologyId, String oboId, String public Page getRoots(String ontologyId, boolean obsolete, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("hasDirectParent", "false", SearchType.WHOLE_FIELD); - query.addFilter("hasHierarchicalParent", "false", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("hasDirectParent", List.of("false"), SearchType.WHOLE_FIELD); + query.addFilter("hasHierarchicalParent", List.of("false"), SearchType.WHOLE_FIELD); if(!obsolete) - query.addFilter("isObsolete", "false", SearchType.WHOLE_FIELD); + query.addFilter("isObsolete", List.of("false"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -106,7 +107,7 @@ public Page getRoots(String ontologyId, boolean obsolete, String lan public Page findAll(String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -116,8 +117,8 @@ public Page findAll(String lang, Pageable pageable) { public Page findAllByIsDefiningOntology(String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -126,8 +127,8 @@ public Page findAllByIsDefiningOntology(String lang, Pageable pageab public Page findAllByIri(String iri, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -137,9 +138,9 @@ public Page findAllByIri(String iri, String lang, Pageable pageable) public Page findAllByIriAndIsDefiningOntology(String iri, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -148,8 +149,8 @@ public Page findAllByIriAndIsDefiningOntology(String iri, String lan public Page findAllByShortForm(String shortForm, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -159,9 +160,9 @@ public Page findAllByShortForm(String shortForm, String lang, Pageab public Page findAllByShortFormAndIsDefiningOntology(String shortForm, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -171,8 +172,8 @@ public Page findAllByShortFormAndIsDefiningOntology(String shortForm public Page findAllByOboId(String oboId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("oboId", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("oboId", List.of(oboId), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); @@ -182,9 +183,9 @@ public Page findAllByOboId(String oboId, String lang, Pageable pagea public Page findAllByOboIdAndIsDefiningOntology(String oboId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("oboId", oboId, SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("oboId", List.of(oboId), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1PropertyMapper.mapProperty(result, lang)); diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1TermRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1TermRepository.java index 5f9550007..f4965be37 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1TermRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v1/V1TermRepository.java @@ -114,9 +114,9 @@ public Page getRelated(String ontologyId, String iri, String lang, Strin public V1Term findByOntologyAndIri(String ontologyId, String iri, String lang) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); JsonElement first; try { @@ -132,9 +132,9 @@ public V1Term findByOntologyAndIri(String ontologyId, String iri, String lang) { public Page findAllByOntology(String ontologyId, Boolean obsoletes, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - if (obsoletes != null) query.addFilter("isObsolete", Boolean.toString(obsoletes), SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + if (obsoletes != null) query.addFilter("isObsolete", List.of(Boolean.toString(obsoletes)), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -143,9 +143,9 @@ public Page findAllByOntology(String ontologyId, Boolean obsoletes, Stri public V1Term findByOntologyAndShortForm(String ontologyId, String shortForm, String lang) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); JsonElement first; try { @@ -160,9 +160,9 @@ public V1Term findByOntologyAndShortForm(String ontologyId, String shortForm, St public V1Term findByOntologyAndOboId(String ontologyId, String oboId, String lang) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("curie", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("curie", List.of(oboId), SearchType.WHOLE_FIELD); JsonElement first; try { @@ -178,13 +178,13 @@ public V1Term findByOntologyAndOboId(String ontologyId, String oboId, String lan public Page getRoots(String ontologyId, boolean obsolete, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.WHOLE_FIELD); - query.addFilter("hasDirectParent", "false", SearchType.WHOLE_FIELD); - query.addFilter("hasHierarchicalParent", "false", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.WHOLE_FIELD); + query.addFilter("hasDirectParent", List.of("false"), SearchType.WHOLE_FIELD); + query.addFilter("hasHierarchicalParent", List.of("false"), SearchType.WHOLE_FIELD); if (!obsolete) - query.addFilter("isObsolete", "false", SearchType.WHOLE_FIELD); + query.addFilter("isObsolete", List.of("false"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -204,7 +204,7 @@ public long getPreferredRootTermCount(String ontologyId, boolean obsolete) { public Page findAll(String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -213,8 +213,8 @@ public Page findAll(String lang, Pageable pageable) { public Page findAllByIsDefiningOntology(String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -224,8 +224,8 @@ public Page findAllByIsDefiningOntology(String lang, Pageable pageable) public Page findAllByIri(String iri, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -234,9 +234,9 @@ public Page findAllByIri(String iri, String lang, Pageable pageable) { public Page findAllByIriAndIsDefiningOntology(String iri, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -245,8 +245,8 @@ public Page findAllByIriAndIsDefiningOntology(String iri, String lang, P public Page findAllByShortForm(String shortForm, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -255,9 +255,9 @@ public Page findAllByShortForm(String shortForm, String lang, Pageable p public Page findAllByShortFormAndIsDefiningOntology(String shortForm, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); - query.addFilter("shortForm", shortForm, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); + query.addFilter("shortForm", List.of(shortForm), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -266,8 +266,8 @@ public Page findAllByShortFormAndIsDefiningOntology(String shortForm, St public Page findAllByOboId(String oboId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("curie", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("curie", List.of(oboId), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); @@ -277,9 +277,9 @@ public Page findAllByOboId(String oboId, String lang, Pageable pageable) public Page findAllByOboIdAndIsDefiningOntology(String oboId, String lang, Pageable pageable) { OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("isDefiningOntology", "true", SearchType.WHOLE_FIELD); - query.addFilter("curie", oboId, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("isDefiningOntology", List.of("true"), SearchType.WHOLE_FIELD); + query.addFilter("curie", List.of(oboId), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(result -> V1TermMapper.mapTerm(result, lang)); diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2ClassRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2ClassRepository.java index 0f4acc897..9e621e734 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2ClassRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2ClassRepository.java @@ -20,6 +20,8 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import java.util.Map; @Component @@ -32,7 +34,7 @@ public class V2ClassRepository { OlsNeo4jClient neo4jClient; public OlsFacetedResultsPage find( - Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map properties) throws IOException { + Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateLang(lang); @@ -43,7 +45,7 @@ public OlsFacetedResultsPage find( OlsSolrQuery query = new OlsSolrQuery(); query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2DynamicFilterParser.addDynamicFiltersToQuery(query, properties); @@ -55,7 +57,7 @@ public OlsFacetedResultsPage find( } public OlsFacetedResultsPage findByOntologyId( - String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map properties) throws IOException { + String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateOntologyId(ontologyId); Validation.validateLang(lang); @@ -68,8 +70,8 @@ public OlsFacetedResultsPage findByOntologyId( query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2DynamicFilterParser.addDynamicFiltersToQuery(query, properties); @@ -87,9 +89,9 @@ public V2Entity getByOntologyIdAndIri(String ontologyId, String iri, String lang OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "class", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("class"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return new V2Entity( RemoveLiteralDatatypesTransform.transform( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2EntityRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2EntityRepository.java index af49d62e6..a5fdc9a9a 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2EntityRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2EntityRepository.java @@ -18,6 +18,8 @@ import uk.ac.ebi.spot.ols.repository.v2.helpers.V2SearchFieldsParser; import java.io.IOException; +import java.util.Collection; +import java.util.List; import java.util.Map; @Component @@ -31,14 +33,14 @@ public class V2EntityRepository { public OlsFacetedResultsPage find( - Pageable pageable, String lang, String search, String searchFields, String boostFields, String facetFields, boolean exactMatch, Map properties) throws IOException { + Pageable pageable, String lang, String search, String searchFields, String boostFields, String facetFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateLang(lang); OlsSolrQuery query = new OlsSolrQuery(); query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "entity", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("entity"), SearchType.WHOLE_FIELD); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2SearchFieldsParser.addFacetFieldsToQuery(query, facetFields); @@ -51,7 +53,7 @@ public OlsFacetedResultsPage find( } public OlsFacetedResultsPage findByOntologyId( - String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, String facetFields, boolean exactMatch, Map properties) throws IOException { + String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, String facetFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateOntologyId(ontologyId); Validation.validateLang(lang); @@ -60,8 +62,8 @@ public OlsFacetedResultsPage findByOntologyId( query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "entity", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("type", List.of("entity"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2SearchFieldsParser.addFacetFieldsToQuery(query, facetFields); @@ -80,9 +82,9 @@ public V2Entity getByOntologyIdAndIri(String ontologyId, String iri, String lang OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "entity", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("entity"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return new V2Entity( RemoveLiteralDatatypesTransform.transform( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2IndividualRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2IndividualRepository.java index 0683d5e0c..ed449380c 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2IndividualRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2IndividualRepository.java @@ -18,6 +18,8 @@ import uk.ac.ebi.spot.ols.repository.v2.helpers.V2SearchFieldsParser; import java.io.IOException; +import java.util.Collection; +import java.util.List; import java.util.Map; @Component @@ -31,7 +33,7 @@ public class V2IndividualRepository { public OlsFacetedResultsPage find( - Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map properties) throws IOException { + Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateLang(lang); @@ -42,7 +44,7 @@ public OlsFacetedResultsPage find( OlsSolrQuery query = new OlsSolrQuery(); query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2DynamicFilterParser.addDynamicFiltersToQuery(query, properties); @@ -54,7 +56,7 @@ public OlsFacetedResultsPage find( } public OlsFacetedResultsPage findByOntologyId( - String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map properties) throws IOException { + String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateOntologyId(ontologyId); Validation.validateLang(lang); @@ -66,8 +68,8 @@ public OlsFacetedResultsPage findByOntologyId( OlsSolrQuery query = new OlsSolrQuery(); query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2DynamicFilterParser.addDynamicFiltersToQuery(query, properties); @@ -85,9 +87,9 @@ public V2Entity getByOntologyIdAndIri(String ontologyId, String iri, String lang Validation.validateLang(lang); OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return new V2Entity( RemoveLiteralDatatypesTransform.transform( @@ -106,9 +108,9 @@ public OlsFacetedResultsPage getInstancesOfClass( Validation.validateLang(lang); OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "individual", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); - query.addFilter("http__//www.w3.org/1999/02/22-rdf-syntax-ns#type", classIri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("individual"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("http__//www.w3.org/1999/02/22-rdf-syntax-ns#type", List.of(classIri), SearchType.WHOLE_FIELD); return solrClient.searchSolrPaginated(query, pageable) .map(e -> LocalizationTransform.transform(e, lang)) diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2OntologyRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2OntologyRepository.java index df3cb9f32..ce050838c 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2OntologyRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2OntologyRepository.java @@ -17,6 +17,9 @@ import uk.ac.ebi.spot.ols.repository.v2.helpers.V2DynamicFilterParser; import uk.ac.ebi.spot.ols.repository.v2.helpers.V2SearchFieldsParser; +import java.util.Collection; +import java.util.List; + import java.io.IOException; import java.util.Map; @@ -31,7 +34,7 @@ public class V2OntologyRepository { public OlsFacetedResultsPage find( - Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map properties) throws IOException { + Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateLang(lang); @@ -43,7 +46,7 @@ public OlsFacetedResultsPage find( query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "ontology", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("ontology"), SearchType.WHOLE_FIELD); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2DynamicFilterParser.addDynamicFiltersToQuery(query, properties); @@ -61,8 +64,8 @@ public V2Entity getById(String ontologyId, String lang) throws ResourceNotFoundE OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "ontology", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("type", List.of("ontology"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); return new V2Entity( LocalizationTransform.transform( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2PropertyRepository.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2PropertyRepository.java index 5030b4193..ef7e8bb8f 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2PropertyRepository.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/V2PropertyRepository.java @@ -20,6 +20,8 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import java.util.Map; @Component @@ -33,7 +35,7 @@ public class V2PropertyRepository { public OlsFacetedResultsPage find( - Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map properties) throws IOException { + Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateLang(lang); @@ -44,7 +46,7 @@ public OlsFacetedResultsPage find( OlsSolrQuery query = new OlsSolrQuery(); query.setSearchText(search); query.setExactMatch(exactMatch); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2DynamicFilterParser.addDynamicFiltersToQuery(query, properties); @@ -56,7 +58,7 @@ public OlsFacetedResultsPage find( } public OlsFacetedResultsPage findByOntologyId( - String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map properties) throws IOException { + String ontologyId, Pageable pageable, String lang, String search, String searchFields, String boostFields, boolean exactMatch, Map> properties) throws IOException { Validation.validateOntologyId(ontologyId); Validation.validateLang(lang); @@ -67,8 +69,8 @@ public OlsFacetedResultsPage findByOntologyId( OlsSolrQuery query = new OlsSolrQuery(); query.setExactMatch(exactMatch); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); V2SearchFieldsParser.addSearchFieldsToQuery(query, searchFields); V2SearchFieldsParser.addBoostFieldsToQuery(query, boostFields); V2DynamicFilterParser.addDynamicFiltersToQuery(query, properties); @@ -86,9 +88,9 @@ public V2Entity getByOntologyIdAndIri(String ontologyId, String iri, String lang Validation.validateLang(lang); OlsSolrQuery query = new OlsSolrQuery(); - query.addFilter("type", "property", SearchType.WHOLE_FIELD); - query.addFilter("ontologyId", ontologyId, SearchType.CASE_INSENSITIVE_TOKENS); - query.addFilter("iri", iri, SearchType.WHOLE_FIELD); + query.addFilter("type", List.of("property"), SearchType.WHOLE_FIELD); + query.addFilter("ontologyId", List.of(ontologyId), SearchType.CASE_INSENSITIVE_TOKENS); + query.addFilter("iri", List.of(iri), SearchType.WHOLE_FIELD); return new V2Entity( RemoveLiteralDatatypesTransform.transform( diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/helpers/V2DynamicFilterParser.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/helpers/V2DynamicFilterParser.java index d4ef017f5..d5469657e 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/helpers/V2DynamicFilterParser.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/v2/helpers/V2DynamicFilterParser.java @@ -3,18 +3,21 @@ import uk.ac.ebi.spot.ols.repository.solr.SearchType; import uk.ac.ebi.spot.ols.repository.solr.OlsSolrQuery; +import java.util.Arrays; +import java.util.Collection; import java.util.Map; public class V2DynamicFilterParser { - public static void addDynamicFiltersToQuery(OlsSolrQuery query, Map properties) { + public static void addDynamicFiltersToQuery(OlsSolrQuery query, Map> properties) { for (String k : properties.keySet()) { if(k.equals("searchFields") || k.equals("boostFields") || k.equals("facetFields") || k.equals("lang")) { continue; } - String value = properties.get(k); - k = k.replace(":", "__"); - query.addFilter(k, value, SearchType.CASE_INSENSITIVE_TOKENS); + for(String v : properties.get(k)) { + String solrKey = k.replace(":", "__"); + query.addFilter(solrKey, Arrays.asList( v.split(",") ), SearchType.CASE_INSENSITIVE_TOKENS); + } } } } From 8570a2d3c595ec0ad6f8b06f33ec28bea0c06989 Mon Sep 17 00:00:00 2001 From: James McLaughlin Date: Wed, 1 Nov 2023 00:30:58 +0000 Subject: [PATCH 2/3] prevent frontend dev server from crashing when api is not running --- frontend/dev_server.mjs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/frontend/dev_server.mjs b/frontend/dev_server.mjs index 56ab91112..1daefcd3c 100644 --- a/frontend/dev_server.mjs +++ b/frontend/dev_server.mjs @@ -15,14 +15,18 @@ if(process.env.OLS_DEV_BACKEND_PROXY_URL === undefined) { server.use(/^\/api.*/, async (req, res) => { let backendUrl = urlJoin(process.env.OLS_DEV_BACKEND_PROXY_URL, req.originalUrl) console.log('forwarding api request to: ' + backendUrl) - let apiResponse = await fetch(backendUrl, { - redirect: 'follow', - method: req.method, - body: req.body - }) - res.header('content-type', apiResponse.headers.get('content-type')) - res.status(apiResponse.status) - apiResponse.body.pipe(res) + try { + let apiResponse = await fetch(backendUrl, { + redirect: 'follow', + method: req.method, + body: req.body + }) + res.header('content-type', apiResponse.headers.get('content-type')) + res.status(apiResponse.status) + apiResponse.body.pipe(res) + } catch(e) { + console.log(e) + } }) From a3d9fce1e0f0a05ad00036e00b9b58f2f5e3249e Mon Sep 17 00:00:00 2001 From: James McLaughlin Date: Wed, 1 Nov 2023 01:50:32 +0000 Subject: [PATCH 3/3] fix faceting in entity search (#170) --- .../uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java | 9 ++++++++- frontend/src/pages/search/searchSlice.ts | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java index a3cab7013..58a895d67 100644 --- a/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/repository/solr/OlsSolrQuery.java @@ -101,6 +101,11 @@ public SolrQuery constructQuery() { for(Filter f : filters) { StringBuilder fq = new StringBuilder(); + + if(facetFields.contains(f.propertyName)) { + fq.append("{!tag=olsfacet}"); + } + fq.append( ClientUtils.escapeQueryChars(getSolrPropertyName(f.propertyName, f.searchType)) ); fq.append(":("); @@ -120,7 +125,9 @@ public SolrQuery constructQuery() { } if(facetFields.size() > 0) { - query.addFacetField(facetFields.toArray(new String[0])); + for(String facetField : facetFields) { + query.addFacetField("{!ex=olsfacet}" + facetField); + } } return query; diff --git a/frontend/src/pages/search/searchSlice.ts b/frontend/src/pages/search/searchSlice.ts index 69990ee93..9fa64c12b 100644 --- a/frontend/src/pages/search/searchSlice.ts +++ b/frontend/src/pages/search/searchSlice.ts @@ -28,8 +28,8 @@ export const getSearchResults = createAsyncThunk( size: rowsPerPage, page, facetFields: "ontologyId type", - ontologyId: ontologyId.length > 0 ? ontologyId[0] : null, - type: type.length > 0 ? type[0] : null, + ontologyId: ontologyId ? ontologyId.join(',') : null, + type: type ? type.join(',') : null, // lang: "all", ...Object.fromEntries(searchParams as URLSearchParams),