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 @@
The encyclopedia API of the nomad@FAIRDI APIs.
"""
import re
import math
import numpy as np
from flask_restplus import Resource, abort, fields, marshal
......@@ -188,7 +187,6 @@ materials_query = api.model("materials_input", {
"after": fields.Nested(materials_after, allow_null=True),
"per_page": fields.Integer(default=25),
"pagination": fields.Boolean,
"mode": fields.String(default="aggregation"),
})),
"material_name": fields.List(fields.String),
"structure_type": fields.List(fields.String),
......@@ -297,7 +295,6 @@ class EncMaterialsResource(Resource):
# Create query for elements or formula
search_by = data["search_by"]
mode = search_by["mode"]
formula = search_by["formula"]
elements = search_by["element"]
exclusive = search_by["exclusive"]
......@@ -365,11 +362,6 @@ class EncMaterialsResource(Resource):
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
s = Search(index=config.elastic.index_name)
s = s.query(bool_query)
......@@ -381,8 +373,14 @@ class EncMaterialsResource(Resource):
# filtered to reduce data transfer.
terms_agg = A("terms", field="encyclopedia.material.material_id")
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:
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.metric("representative", A(
"top_hits",
......@@ -400,7 +398,7 @@ class EncMaterialsResource(Resource):
materials = response.aggs.materials.buckets
if len(materials) == 0:
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
result_list = []
......@@ -416,41 +414,12 @@ class EncMaterialsResource(Resource):
pages = {
"page": 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 len(response) == 0:
abort(404, message="No materials found for the given search criteria or pagination.")
# 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,
}
if after is None:
n_materials = response.aggs.n_materials.value
pages["total"] = n_materials
result = {
"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