Commit 66e49012 authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Added the number of total results on the material list page.

parent 9d785f3f
Pipeline #76825 passed with stages
in 20 minutes and 34 seconds
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
The encyclopedia API of the nomad@FAIRDI APIs. The encyclopedia API of the nomad@FAIRDI APIs.
""" """
import re import re
import math
import numpy as np import numpy as np
from flask_restplus import Resource, abort, fields, marshal from flask_restplus import Resource, abort, fields, marshal
...@@ -188,7 +187,6 @@ materials_query = api.model("materials_input", { ...@@ -188,7 +187,6 @@ materials_query = api.model("materials_input", {
"after": fields.Nested(materials_after, allow_null=True), "after": fields.Nested(materials_after, allow_null=True),
"per_page": fields.Integer(default=25), "per_page": fields.Integer(default=25),
"pagination": fields.Boolean, "pagination": fields.Boolean,
"mode": fields.String(default="aggregation"),
})), })),
"material_name": fields.List(fields.String), "material_name": fields.List(fields.String),
"structure_type": fields.List(fields.String), "structure_type": fields.List(fields.String),
...@@ -297,7 +295,6 @@ class EncMaterialsResource(Resource): ...@@ -297,7 +295,6 @@ class EncMaterialsResource(Resource):
# Create query for elements or formula # Create query for elements or formula
search_by = data["search_by"] search_by = data["search_by"]
mode = search_by["mode"]
formula = search_by["formula"] formula = search_by["formula"]
elements = search_by["element"] elements = search_by["element"]
exclusive = search_by["exclusive"] exclusive = search_by["exclusive"]
...@@ -365,11 +362,6 @@ class EncMaterialsResource(Resource): ...@@ -365,11 +362,6 @@ class EncMaterialsResource(Resource):
must=musts, must=musts,
) )
# 1: The paginated approach: No way to know the amount of materials,
# but can return aggregation results in a quick fashion including
# the number of calculation entries per material.
if mode == "aggregation":
# The top query filters out entries based on the user query # The top query filters out entries based on the user query
s = Search(index=config.elastic.index_name) s = Search(index=config.elastic.index_name)
s = s.query(bool_query) s = s.query(bool_query)
...@@ -381,8 +373,14 @@ class EncMaterialsResource(Resource): ...@@ -381,8 +373,14 @@ class EncMaterialsResource(Resource):
# filtered to reduce data transfer. # filtered to reduce data transfer.
terms_agg = A("terms", field="encyclopedia.material.material_id") terms_agg = A("terms", field="encyclopedia.material.material_id")
composite_kwargs = {"sources": {"materials": terms_agg}, "size": per_page} composite_kwargs = {"sources": {"materials": terms_agg}, "size": per_page}
# The number of matched materials is only requested on the first
# search, not for each page.
if after is not None: if after is not None:
composite_kwargs["after"] = after composite_kwargs["after"] = after
else:
cardinality_agg = A("cardinality", field="encyclopedia.material.material_id")
s.aggs.metric("n_materials", cardinality_agg)
composite_agg = A("composite", **composite_kwargs) composite_agg = A("composite", **composite_kwargs)
composite_agg.metric("representative", A( composite_agg.metric("representative", A(
"top_hits", "top_hits",
...@@ -400,7 +398,7 @@ class EncMaterialsResource(Resource): ...@@ -400,7 +398,7 @@ class EncMaterialsResource(Resource):
materials = response.aggs.materials.buckets materials = response.aggs.materials.buckets
if len(materials) == 0: if len(materials) == 0:
abort(404, message="No materials found for the given search criteria or pagination.") abort(404, message="No materials found for the given search criteria or pagination.")
after = response.aggs.materials["after_key"] after_new = response.aggs.materials["after_key"]
# Gather results from aggregations # Gather results from aggregations
result_list = [] result_list = []
...@@ -416,41 +414,12 @@ class EncMaterialsResource(Resource): ...@@ -416,41 +414,12 @@ class EncMaterialsResource(Resource):
pages = { pages = {
"page": page, "page": page,
"per_page": per_page, "per_page": per_page,
"after": after, "after": after_new,
} }
# 2. Collapse approach. Quickly provides a list of materials
# corresponding to the query, offers full pagination, doesn"t include
# the number of matches per material.
elif mode == "collapse":
s = Search(index=config.elastic.index_name)
s = s.query(bool_query)
s = s.extra(**{
"collapse": {"field": "encyclopedia.material.material_id"},
"size": per_page,
"from": (page - 1) * per_page,
})
# Execute query
response = s.execute()
# No matches if after is None:
if len(response) == 0: n_materials = response.aggs.n_materials.value
abort(404, message="No materials found for the given search criteria or pagination.") pages["total"] = n_materials
# Loop over materials
result_list = []
keys = list(material_prop_map.keys())
for material in response:
mat_result = get_es_doc_values(material, material_prop_map, keys)
result_list.append(mat_result)
# Full page information available for collapse
pages = {
"page": page,
"per_page": per_page,
"pages": math.ceil(response.hits.total / per_page),
"total": response.hits.total,
}
result = { result = {
"results": result_list, "results": result_list,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment