Skip to content

Commit

Permalink
Facet groups can be either a list as of now, or a dict with keys bein…
Browse files Browse the repository at this point in the history
…g facet group names and values their priority (lower comes first). Facets without a priority go after the facets with explicit priority.
  • Loading branch information
mesemus committed Feb 25, 2024
1 parent 92ce9c4 commit 0d65b9c
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class FacetDefinition:
dot_path: str
searchable: bool
imports: List[Dict[str, str]]
facet_groups: List[str]
facet_groups: Dict[str, int]
facet: Optional[bool]
field: Optional[str] = None

Expand Down
21 changes: 18 additions & 3 deletions oarepo_model_builder/datatypes/components/facets/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
from . import FacetDefinition


class FacetGroupsDict(fields.Dict):
def _deserialize(self, value, attr, data, **kwargs):
transformed_value = {}
if isinstance(value, list):
for val in value:
if isinstance(val, str):
transformed_value[val] = 100000
else:
transformed_value.update(val)
else:
transformed_value = value
return super()._deserialize(transformed_value, attr, data, **kwargs)


class FacetsSchema(ma.Schema):
class Meta:
unknown = ma.RAISE
Expand All @@ -23,8 +37,9 @@ class Meta:
imports = fields.List(fields.Nested(ImportSchema), required=False)
path = fields.String(required=False)
keyword = fields.String(required=False)
facet_groups = fields.List(
fields.String(),
facet_groups = FacetGroupsDict(
keys=fields.String(),
values=fields.Integer(),
required=False,
data_key="facet-groups",
attribute="facet-groups",
Expand Down Expand Up @@ -60,7 +75,7 @@ def process_facets(self, datatype, section, **__kwargs):
searchable=facet_section.get("searchable"),
imports=facet_section.get("imports", []),
facet=facet_section.get("facet", None),
facet_groups=facet_section.get("facet-groups", ["_default"]),
facet_groups=facet_section.get("facet-groups", {"_default": 100000}),
)

# set the field on the definition
Expand Down
36 changes: 31 additions & 5 deletions oarepo_model_builder/invenio/invenio_record_search_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,45 @@ def finish(self, **extra_kwargs):
facet_groups = {}
default_group = []
search_data = []

# gather all facet group names
facet_group_names = set()
for f in facets:
facet_group_names.update(f.facet_groups.keys())

# for each group name, gather all facets with that group name
# sort them by their order in the group
# and add them to the facet_groups dict
for group in sorted(facet_group_names):
# skip the default group
if group == "_default":
continue

# gather all facets with this facet_group_name
group_members = []
for f in facets:
if group in f.facet_groups:
group_members.append((f, f.facet_groups[group]))

# sort the group members by their order in the facet_group
group_members.sort(key=lambda x: x[1])

if group not in facet_groups.keys():
facet_groups[group] = {}

for f, _ in group_members:
facet_groups[group][f.path] = "facets." + f.path

for f in facets:
for group in f.facet_groups:
if group != "_default":
if group not in facet_groups.keys():
facet_groups[group] = {}
facet_groups[group][f.path] = "facets." + f.path
if len(f.facet_groups) > 0:
default_group.append({f.path: "facets." + f.path})
search_data.append({f.path: "facets." + f.path})

if "sortable" in self.current_model.definition:
sort_options = self.current_model.definition["sortable"]
else:
sort_options = {}

extra_kwargs["facet_groups"] = facet_groups
extra_kwargs["default_group"] = default_group
extra_kwargs["sort_definition"] = sort_options
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = oarepo-model-builder
version = 4.0.74
version = 4.0.75
description = A utility library that generates OARepo required data model files from a JSON specification file
authors = Miroslav Bauer <[email protected]>, Miroslav Simek <[email protected]>
readme = README.md
Expand Down
93 changes: 68 additions & 25 deletions tests/test_search_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,40 +316,19 @@ class TestSearchOptions(BaseSearchOptions):
\"""TestRecord search options.\"""
facet_groups ={
'curator': {
'a' : facets.a,
'g' : facets.g,
**getattr(BaseSearchOptions, 'facet_groups', {}).get('curator', {})
},
'user': {
'a' : facets.a,
**getattr(BaseSearchOptions, 'facet_groups', {}).get('user', {})
},
'default': {
'b3' : facets.b3,
**getattr(BaseSearchOptions, 'facet_groups', {}).get('default', {})
},
'user': {
'a' : facets.a,
**getattr(BaseSearchOptions, 'facet_groups', {}).get('user', {})
},
}
facets = {
Expand Down Expand Up @@ -382,6 +361,70 @@ class TestSearchOptions(BaseSearchOptions):
)


def test_facet_groups_ordering():
schema = load_model(
DUMMY_YAML,
model_content={
"record": {
"use": "invenio",
"module": {"qualified": "test"},
"search-options": {
"base-classes": ["BaseSearchOptions"],
"imports": [{"import": "blah.BaseSearchOptions"}],
},
"properties": {
"a": {
"type": "keyword",
"facets": {"facet-groups": {"curator": 2}},
},
"b": {
"type": "keyword",
"facets": {"facet-groups": {"curator": 3}},
},
"c": {
"type": "keyword",
"facets": {"facet-groups": {"curator": 1}},
},
},
},
},
isort=False,
black=False,
autoflake=False,
)

filesystem = InMemoryFileSystem()
builder = create_builder_from_entrypoints(filesystem=filesystem)

builder.build(schema, "record", ["record"], "")

data = builder.filesystem.open(
os.path.join("test", "services", "records", "search.py")
).read()
print(data)
data2 = builder.filesystem.open(
os.path.join("test", "services", "records", "facets.py")
).read()
print(data2)
data3 = builder.filesystem.read(
os.path.join("test", "records", "mappings", "os-v2", "test", "test-1.0.0.json")
)
import json

data3 = json.loads(data3)
print(data3)
assert (
strip_whitespaces(
"""
'c': facets.c,
'a': facets.a,
'b': facets.b,
"""
)
in strip_whitespaces(data)
)


def test_replace_sort_options():
schema = load_model(
DUMMY_YAML,
Expand Down

0 comments on commit 0d65b9c

Please sign in to comment.