diff --git a/omero_search_engine/api/v1/resources/resource_analyser.py b/omero_search_engine/api/v1/resources/resource_analyser.py index 877a3bad..7eed09ba 100644 --- a/omero_search_engine/api/v1/resources/resource_analyser.py +++ b/omero_search_engine/api/v1/resources/resource_analyser.py @@ -802,23 +802,33 @@ def get_the_results(resource, name, description, es_index="key_values_resource_c return returned_results -def get_container_values_for_key(table_, container_name, csv, key=None): - returned_results = [] +def get_containets_from_name(container_name): + act_names = {} pr_names = get_resource_names("all") for resourse, names in pr_names.items(): - act_name = [ + act_names[resourse] = [ {"id": name["id"], "name": name["name"]} for name in names if name["name"] and container_name.lower() in name["name"].lower() ] + + return act_names + + +def get_container_values_for_key(table_, container_name, csv, key=None, query=None): + returned_results = [] + act_names = get_containets_from_name(container_name) + for resourse, act_name in act_names.items(): if len(act_name) > 0: for id in act_name: if resourse != table_: res = process_container_query( - table_, resourse + "_id", id["id"], key, table_ + table_, resourse + "_id", id["id"], key, table_, query ) else: - res = process_container_query(table_, "id", id["id"], key, table_) + res = process_container_query( + table_, "id", id["id"], key, table_, query + ) if len(res) > 0: returned_results.append( {"name": id["name"], "type": resourse, "results": res} @@ -865,7 +875,9 @@ def get_container_values_for_key(table_, container_name, csv, key=None): return jsonify(returned_results) -def process_container_query(table_, attribute_name, container_id, key, resourse): +def process_container_query( + table_, attribute_name, container_id, key, resourse, query=None +): from omero_search_engine.api.v1.resources.utils import elasticsearch_query_builder res_index = resource_elasticsearchindex.get(table_) @@ -874,7 +886,15 @@ def process_container_query(table_, attribute_name, container_id, key, resourse) {"name": attribute_name, "value": container_id, "operator": "equals"} ] } - query_ = elasticsearch_query_builder([], [], False, main_attributes=main_attributes) + if query: + and_filter = query.get("query_details").get("and_filters") + or_filters = query.get("query_details").get("or_filters") + else: + and_filter = [] + or_filters = [] + query_ = elasticsearch_query_builder( + and_filter, or_filters, False, main_attributes=main_attributes + ) query = json.loads(query_) if key: query["aggs"] = json.loads( diff --git a/omero_search_engine/api/v1/resources/swagger_docs/container_filterkeyvalues.yml b/omero_search_engine/api/v1/resources/swagger_docs/container_filterkeyvalues.yml new file mode 100644 index 00000000..5031b4ba --- /dev/null +++ b/omero_search_engine/api/v1/resources/swagger_docs/container_filterkeyvalues.yml @@ -0,0 +1,69 @@ +Return the available key values within a container which within a query results +Example + +In this example the search will use the provided query results within the specified container and provides the aviable values for the provided key. + +The query: + +{ + "resource": "image", + "query_details": { + "and_filters": [ + { + "name": "Organism", + "value": "homo sapiens", + "operator": "equals", + "resource": "image" + }, + { + "name": "Organism part", + "value": "Brain", + "operator": "equals", + "resource": "image" + }, + ], + "or_filters": [ + + ], + "case_sensitive": false + } + } + +The user needs to specify +- the container name, e.g. "idr0043-uhlen-humanproteinatlas/experimentA" +- the key which its values is needed, e.g. "gene symbol" + +the results should contains buckets like this: +{ + "key": "Gene symbol", + "no_image": 146, + "value": "NBPF12" +} +--- +tags: + - Return available key values with a search results in a container +parameters: + - name: resource_table + in: path + type: string + enum: ['image', 'project', 'screen', 'well', 'plate'] + required: true + default: 'image' + - name: data + in: body + required: true + - name: container_name + in: query + type: string + required: true + + - name: key + in: query + type: string + required: true + +responses: + 200: + description: A JSON contains the results + examples: + results: [] diff --git a/omero_search_engine/api/v1/resources/urls.py b/omero_search_engine/api/v1/resources/urls.py index 77a3f037..fc1dbf83 100644 --- a/omero_search_engine/api/v1/resources/urls.py +++ b/omero_search_engine/api/v1/resources/urls.py @@ -389,6 +389,37 @@ def search(resource_table): return jsonify(results) +@resources.route("//container_filterkeyvalues/", methods=["POST"]) +def container_key_values_filter(resource_table): + """ + file: swagger_docs/container_filterkeyvalues.yml + """ + from omero_search_engine.api.v1.resources.resource_analyser import ( + get_container_values_for_key, + ) + + key = request.args.get("key") + container_name = request.args.get("container_name") + if not container_name or not key: + return build_error_message("Container name and key are required") + + data = request.data + try: + query = json.loads(data) + except Exception: + return jsonify( + build_error_message( + "{error}".format(error="No proper query data is provided ") + ) + ) + validation_results = query_validator(query) + if validation_results != "OK": + return jsonify(build_error_message(validation_results)) + return get_container_values_for_key( + resource_table, container_name, None, key, query + ) + + @resources.route("//container_keyvalues/", methods=["GET"]) def container_key_values_search(resource_table): """