ols4
ols4 copied to clipboard
What should the search APIs look like in v4?
In OLS3 we have a complicated /api/search
endpoint:
@RequestMapping(path = "/api/search", produces = {MediaType.APPLICATION_JSON_VALUE}, method = RequestMethod.GET)
public void search(
@RequestParam("q") String query,
@RequestParam(value = "ontology", required = false) Collection<String> ontologies,
@RequestParam(value = "type", required = false) Collection<String> types,
@RequestParam(value= "slim", required = false) Collection<String> slims,
@RequestParam(value = "fieldList", required = false) Collection<String> fieldList,
@RequestParam(value = "queryFields", required = false) Collection<String> queryFields,
@RequestParam(value = "exact", required = false) boolean exact,
@RequestParam(value = "groupField", required = false) String groupField,
@RequestParam(value = "obsoletes", defaultValue = "false") boolean queryObsoletes,
@RequestParam(value = "local", defaultValue = "false") boolean isLocal,
@RequestParam(value = "childrenOf", required = false) Collection<String> childrenOf,
@RequestParam(value = "allChildrenOf", required = false) Collection<String> allChildrenOf,
@RequestParam(value = "inclusive", required = false) boolean inclusive,
@RequestParam(value = "isLeaf", required = false) boolean isLeaf,
@RequestParam(value = "rows", defaultValue = "10") Integer rows,
@RequestParam(value = "start", defaultValue = "0") Integer start,
@RequestParam(value = "format", defaultValue = "json") String format,
which is implemented with this logic:
if (queryFields == null) {
// if exact just search the supplied fields for exact matches
if (exact) {
// todo remove shortform_s once indexes have rebuilt - see https://helpdesk.ebi.ac.uk/Ticket/Display.html?id=75961
solrQuery.setQuery(
"((" +
createUnionQuery(query.toLowerCase(), "label_s", "synonym_s", "shortform_s", "short_form_s", "obo_id_s", "iri_s", "annotations_trimmed")
+ ") AND (is_defining_ontology:true^100 OR is_defining_ontology:false^0))"
);
}
else {
solrQuery.set("defType", "edismax");
solrQuery.setQuery(query);
solrQuery.set("qf", "label^5 synonym^3 description short_form^2 obo_id^2 annotations logical_description iri");
solrQuery.set("bq", "type:ontology^10.0 is_defining_ontology:true^100 label_s:\"" + query.toLowerCase() + "\"^5 synonym_s:\"" + query.toLowerCase() + "\"^3 annotations_trimmed:\"" + query.toLowerCase() + "\"");
}
}
else {
if (exact) {
List<String> fieldS = queryFields.stream()
.map(addStringField).collect(Collectors.toList());
solrQuery.setQuery( createUnionQuery(query, fieldS.toArray(new String [fieldS.size()])));
}
else {
solrQuery.set("defType", "edismax");
solrQuery.setQuery(query);
solrQuery.set("qf", String.join(" ", queryFields));
}
}
We will of course reimplement all of this in the OLS3 compatibility layer (and everything is in place apart from the API server code to do so).
For the new API I've been trying to make search an integral part of the same endpoints you use to retrieve entities. For example, you can retrieve:
`/api/v2/classes`
to get all classes, or you can retrieve:
`/api/v2/classes?search=diabetes`
to search for all classes with diabetes in some set of hardcoded fields (at least label, definition, uri off the top of my head), or:
`/api/v2/classes?search=diabetes&searchFields=label^10%20definition^5`
to search in label boosted 10 and definition boosted 5. You can also search in ANY field by including it in the GET parameters, like:
`/api/v2/classes?label=diabetes`
This includes fields that are specific to certain ontologies, like e.g. INCHIKEY in ChEBI. However, we are restricted by the expressivity of GET parameters. What if I want to search one of the fields exactly and the other case insensitively? Maybe a JSON POST search endpoint would be better?