diff --git a/geonode/facets/providers/category.py b/geonode/facets/providers/category.py index 6b7dc331768..488d5ab2e41 100644 --- a/geonode/facets/providers/category.py +++ b/geonode/facets/providers/category.py @@ -39,14 +39,14 @@ def name(self) -> str: def get_info(self, lang="en", **kwargs) -> dict: return { "name": self.name, - "filter": "filter{category.identifier}", + "filter": "filter{category.identifier.in}", "label": "Category", "type": FACET_TYPE_CATEGORY, } def get_facet_items( self, - queryset=None, + queryset, start: int = 0, end: int = DEFAULT_FACET_PAGE_SIZE, lang="en", @@ -56,22 +56,26 @@ def get_facet_items( ) -> (int, list): logger.debug("Retrieving facets for %s", self.name) - filters = {"category__isnull": False} + filters = {"resourcebase__in": queryset} if topic_contains: - filters["category__gn_description"] = topic_contains + filters["gn_description__icontains"] = topic_contains if keys: logger.debug("Filtering by keys %r", keys) - filters["category__identifier__in"] = keys + filters["identifier__in"] = keys q = ( - queryset.values("category__identifier", "category__gn_description", "category__fa_class") + TopicCategory.objects.values("identifier", "gn_description", "fa_class") .filter(**filters) - .annotate(count=Count("owner")) + .annotate(count=Count("resourcebase")) .order_by("-count") ) + logger.debug(" PREFILTERED QUERY ---> %s\n\n", queryset.query) + logger.debug(" ADDITIONAL FILTERS ---> %s\n\n", filters) + logger.debug(" FINAL QUERY ---> %s\n\n", q.query) + cnt = q.count() logger.info("Found %d facets for %s", cnt, self.name) @@ -80,10 +84,10 @@ def get_facet_items( topics = [ { - "key": r["category__identifier"], - "label": r["category__gn_description"], + "key": r["identifier"], + "label": r["gn_description"], "count": r["count"], - "fa_class": r["category__fa_class"], + "fa_class": r["fa_class"], } for r in q[start:end].all() ] diff --git a/geonode/facets/providers/keyword.py b/geonode/facets/providers/keyword.py index 41c4a470cfa..476031f9e31 100644 --- a/geonode/facets/providers/keyword.py +++ b/geonode/facets/providers/keyword.py @@ -56,18 +56,18 @@ def get_facet_items( ) -> (int, list): logger.debug("Retrieving facets for %s", self.name) - filters = {"keywords__isnull": False} + filters = {"resourcebase__in": queryset} if topic_contains: - filters["keywords__name__icontains"] = topic_contains + filters["name__icontains"] = topic_contains if keys: logger.debug("Filtering by keys %r", keys) - filters["keywords__slug__in"] = keys + filters["slug__in"] = keys q = ( - queryset.filter(**filters) - .values("keywords__slug", "keywords__name") - .annotate(count=Count("keywords__slug")) + HierarchicalKeyword.objects.filter(**filters) + .values("slug", "name") + .annotate(count=Count("resourcebase")) .order_by("-count") ) @@ -79,8 +79,8 @@ def get_facet_items( topics = [ { - "key": r["keywords__slug"], - "label": r["keywords__name"], + "key": r["slug"], + "label": r["name"], "count": r["count"], } for r in q[start:end].all() diff --git a/geonode/facets/providers/region.py b/geonode/facets/providers/region.py index bd912ab8693..73a7e578d37 100644 --- a/geonode/facets/providers/region.py +++ b/geonode/facets/providers/region.py @@ -46,7 +46,7 @@ def get_info(self, lang="en", **kwargs) -> dict: def get_facet_items( self, - queryset=None, + queryset, start: int = 0, end: int = DEFAULT_FACET_PAGE_SIZE, lang="en", @@ -56,19 +56,19 @@ def get_facet_items( ) -> (int, list): logger.debug("Retrieving facets for %s", self.name) - filters = {"regions__isnull": False} + filters = {"resourcebase__in": queryset} if topic_contains: - filters["regions__name"] = topic_contains + filters["name__icontains"] = topic_contains if keys: logger.debug("Filtering by keys %r", keys) - filters["regions__code__in"] = keys + filters["code__in"] = keys q = ( - queryset.filter(**filters) - .values("regions__code", "regions__name") - .annotate(count=Count("regions__code")) + Region.objects.filter(**filters) + .values("code", "name") + .annotate(count=Count("resourcebase")) .order_by("-count") ) @@ -80,8 +80,8 @@ def get_facet_items( topics = [ { - "key": r["regions__code"], - "label": r["regions__name"], + "key": r["code"], + "label": r["name"], "count": r["count"], } for r in q[start:end].all() diff --git a/geonode/facets/providers/thesaurus.py b/geonode/facets/providers/thesaurus.py index 047ac9b82ea..92621340394 100644 --- a/geonode/facets/providers/thesaurus.py +++ b/geonode/facets/providers/thesaurus.py @@ -56,7 +56,7 @@ def get_info(self, lang="en", **kwargs) -> dict: def get_facet_items( self, - queryset=None, + queryset, start: int = 0, end: int = DEFAULT_FACET_PAGE_SIZE, lang="en", @@ -66,30 +66,30 @@ def get_facet_items( ) -> (int, list): logger.debug("Retrieving facets for %s", self._name) - filter = { - "tkeywords__thesaurus__identifier": self._name, - } + filter = {"thesaurus__identifier": self._name, "resourcebase__in": queryset} if topic_contains: - filter["tkeywords__keyword__label__icontains"] = topic_contains + filter["label__icontains"] = topic_contains if keys: logger.debug("Filtering by keys %r\n", keys) - filter["tkeywords__in"] = keys + filter["id__in"] = keys q = ( - queryset.filter(**filter) - .values("tkeywords", "tkeywords__alt_label", "tkeywords__image") - .annotate(count=Count("tkeywords")) + ThesaurusKeyword.objects.filter(**filter) + .values("id", "alt_label", "image") + .annotate(count=Count("resourcebase")) .annotate( localized_label=Subquery( - ThesaurusKeywordLabel.objects.filter(keyword=OuterRef("tkeywords"), lang=lang).values("label") + ThesaurusKeywordLabel.objects.filter(keyword=OuterRef("id"), lang=lang).values("label") ) ) .order_by("-count") ) - logger.debug(" ---> %s\n\n", q.query) + logger.debug(" PREFILTERED QUERY ---> %s\n\n", queryset.query) + logger.debug(" ADDITIONAL FILTERS ---> %s\n\n", filter) + logger.debug(" FINAL QUERY ---> %s\n\n", q.query) cnt = q.count() @@ -98,11 +98,11 @@ def get_facet_items( topics = [ { - "key": r["tkeywords"], - "label": r["localized_label"] or r["tkeywords__alt_label"], + "key": r["id"], + "label": r["localized_label"] or r["alt_label"], "is_localized": r["localized_label"] is not None, "count": r["count"], - "image": r["tkeywords__image"], + "image": r["image"], } for r in q[start:end].all() ] @@ -111,7 +111,7 @@ def get_facet_items( def get_topics(self, keys: list, lang="en", **kwargs) -> list: q = ( - ThesaurusKeyword.objects.filter(id__in=keys) + ThesaurusKeyword.objects.filter(id__in=keys, thesaurus__identifier=self.name) .values("id", "alt_label") .annotate( localized_label=Subquery( diff --git a/geonode/facets/tests.py b/geonode/facets/tests.py index 8b4812a110f..c227b152e35 100644 --- a/geonode/facets/tests.py +++ b/geonode/facets/tests.py @@ -119,6 +119,7 @@ def _create_categories(cls): ("C0", "Cat0"), ("C1", "Cat1"), ("C2", "Cat2"), + ("C3", "Cat3"), ): cls.cats[code] = TopicCategory.objects.create(identifier=code, description=name, gn_description=name) @@ -130,6 +131,7 @@ def _create_keywords(cls): ("K0", "Keyword0"), ("K1", "Keyword1"), ("K2", "Keyword2"), + ("K3", "Keyword3"), ): cls.kw[code] = HierarchicalKeyword.objects.create(slug=code, name=name) @@ -150,26 +152,26 @@ def _create_resources(self): # These are the assigned keywords to the Resources - # RB00 -> T1K0 R0,R1 FEAT K0 C0 - # RB01 -> T0K0 T1K0 R0 FEAT K1 - # RB02 -> T1K0 R1 FEAT K2 C0 - # RB03 -> T0K0 T1K0 K0 - # RB04 -> T1K0 K0,K1 C0 - # RB05 -> T0K0 T1K0 K0,K2 C1 - # RB06 -> T1K0 FEAT - # RB07 -> T0K0 T1K0 FEAT - # RB08 -> T1K0 T1K1 R1 FEAT - # RB09 -> T0K0 T1K0 T1K1 - # RB10 -> T1K1 - # RB11 -> T0K0 T0K1 T1K1 - # RB12 -> T1K1 FEAT - # RB13 -> T0K0 T0K1 R1 FEAT - # RB14 -> FEAT - # RB15 -> T0K0 T0K1 C1 - # RB16 -> C1 - # RB17 -> T0K0 T0K1 - # RB18 -> FEAT C2 - # RB19 -> T0K0 T0K1 FEAT C2 + # RB00 -> T1K0 R0,R1 FEAT K0 C0 + # RB01 -> T0K0 T1K0 R0 FEAT K1 + # RB02 -> T1K0 R1 FEAT K2 C0 + # RB03 -> T0K0 T1K0 K0 + # RB04 -> T1K0 K0K1 C0 + # RB05 -> T0K0 T1K0 K0 K2 C1 + # RB06 -> T1K0 FEAT + # RB07 -> T0K0 T1K0 R2 FEAT K3 C3 + # RB08 -> T1K0 T1K1 R1,R2 FEAT K3 C3 + # RB09 -> T0K0 T1K0 T1K1 R2 K3 C3 + # RB10 -> T1K1 R2 K3 C3 + # RB11 -> T0K0 T0K1 T1K1 + # RB12 -> T1K1 FEAT + # RB13 -> T0K0 T0K1 R1 FEAT + # RB14 -> FEAT + # RB15 -> T0K0 T0K1 C1 + # RB16 -> C1 + # RB17 -> T0K0 T0K1 + # RB18 -> FEAT C2 + # RB19 -> T0K0 T0K1 FEAT C2 if x % 2 == 1: logger.debug(f"ADDING KEYWORDS {self.thesauri_k['0_0']} to RB {d}") @@ -189,6 +191,7 @@ def _create_resources(self): for reg, idx in ( # fmt: skip ("R0", (0, 1)), ("R1", (0, 2, 8, 13)), + ("R2", (7, 8, 9, 10)), ): if x in idx: d.regions.add(self.regions[reg]) @@ -197,6 +200,7 @@ def _create_resources(self): ("K0", (0, 3, 4, 5)), ("K1", [1, 4]), ("K2", [2, 5]), + ("K3", [7, 8, 9, 10]), ): if x in idx: d.keywords.add(self.kw[kw]) @@ -205,6 +209,7 @@ def _create_resources(self): ("C0", [0, 2, 4]), ("C1", [5, 15, 16]), ("C2", [18, 19]), + ("C3", [7, 8, 9, 10]), ): if x in idx: d.category = self.cats[cat] @@ -248,10 +253,11 @@ def test_facets_rich(self): { "name": "category", "topics": { - "total": 3, + "total": 4, "items": [ {"label": "Cat0", "count": 3}, {"label": "Cat1", "count": 3}, + {"label": "Cat3", "count": 4}, {"label": "Cat2", "count": 2}, ], }, @@ -259,11 +265,12 @@ def test_facets_rich(self): { "name": "keyword", "topics": { - "total": 3, + "total": 4, "items": [ {"label": "Keyword0", "count": 4}, {"label": "Keyword1", "count": 2}, {"label": "Keyword2", "count": 2}, + {"label": "Keyword3", "count": 4}, ], }, }, @@ -295,10 +302,11 @@ def test_facets_rich(self): { "name": "region", "topics": { - "total": 2, + "total": 3, "items": [ {"label": "Region0", "key": "R0", "count": 2}, {"label": "Region1", "key": "R1", "count": 4}, + {"label": "Region2", "key": "R2", "count": 4}, ], }, }, @@ -386,15 +394,21 @@ def test_prefiltering(self): ("t_1", {}, 2, 10), ("t_1", {regfilter: "R0"}, 1, 2), ("t_1", {regfilter: "R1"}, 2, 3), - (reginfo["name"], {}, 2, 4), - (reginfo["name"], {t0filter: self.thesauri_k["0_0"].id}, 2, 1), - (reginfo["name"], {t1filter: self.thesauri_k["1_0"].id}, 2, 3), + (reginfo["name"], {}, 3, 4), + (reginfo["name"], {t0filter: self.thesauri_k["0_0"].id}, 3, 2), + (reginfo["name"], {t1filter: self.thesauri_k["1_0"].id}, 3, 3), ): req = self.rf.get(reverse("get_facet", args=[facet]), data=filters) res: JsonResponse = GetFacetView.as_view()(req, facet) obj = json.loads(res.content) - self.assertEqual(totals, obj["topics"]["total"], f"Bad totals for facet '{facet} and filter {filters}") - self.assertEqual(count0, obj["topics"]["items"][0]["count"], f"Bad count0 for facet '{facet}") + self.assertEqual( + totals, + obj["topics"]["total"], + f"Bad totals for facet '{facet} and filter {filters}\nRESPONSE: {obj}", + ) + self.assertEqual( + count0, obj["topics"]["items"][0]["count"], f"Bad count0 for facet '{facet}\nRESPONSE: {obj}" + ) def test_prefiltering_tkeywords(self): regname = RegionFacetProvider().name @@ -402,7 +416,7 @@ def test_prefiltering_tkeywords(self): t1filter = facet_registry.get_provider("t_1").get_info()["filter"] tkey_1_1 = self.thesauri_k["1_1"].id - expected_region = {"R1": 1} + expected_region = {"R1": 1, "R2": 3} expected_feat = {True: 2, False: 3} # Run the single requests @@ -471,48 +485,61 @@ def test_config(self): def test_count0(self): reginfo = RegionFacetProvider().get_info() - regfilter = reginfo["filter"] + regflt = reginfo["filter"] regname = reginfo["name"] catinfo = CategoryFacetProvider().get_info() + catflt = catinfo["filter"] catname = catinfo["name"] kwinfo = KeywordFacetProvider().get_info() - kwfilter = kwinfo["filter"] + kwflt = kwinfo["filter"] kwname = kwinfo["name"] - t0filter = facet_registry.get_provider("t_0").get_info()["filter"] - t1filter = facet_registry.get_provider("t_1").get_info()["filter"] + t0flt = facet_registry.get_provider("t_0").get_info()["filter"] + t1flt = facet_registry.get_provider("t_1").get_info()["filter"] def t(tk): return self.thesauri_k[tk].id - for facet, params, items in ( + for facet, params, items in ( # fmt: skip # thesauri - ("t_1", {regfilter: "R0"}, {t("1_0"): 2}), - ("t_1", {regfilter: "R0", "key": [t("1_0")]}, {t("1_0"): 2}), - ("t_1", {regfilter: "R0", t0filter: t("0_1")}, {}), - ("t_1", {regfilter: "R0", t0filter: t("0_1"), "key": [t("1_0")]}, {t("1_0"): None}), + ("t_1", {regflt: "R0"}, {t("1_0"): 2}), + ("t_1", {regflt: "R0", "key": [t("1_0")]}, {t("1_0"): 2}), + ("t_1", {regflt: "R0", t0flt: t("0_1")}, {}), + ("t_1", {regflt: "R0", t0flt: t("0_1"), "key": [t("1_0")]}, {t("1_0"): None}), ( "t_1", - {regfilter: "R0", t0filter: t("0_1"), "key": [t("1_1"), t("1_0")]}, + {regflt: "R0", t0flt: t("0_1"), "key": [t("1_1"), t("1_0")]}, {t("1_0"): None, t("1_1"): None}, ), + ("t_1", {"key": [t("0_1")]}, {}), + ("t_1", {t0flt: t("0_0")}, {t("1_0"): 5, t("1_1"): 2}), + ("t_1", {t0flt: t("0_1")}, {t("1_1"): 1}), + ("t_1", {t0flt: [t("0_1"), t("0_0")]}, {t("1_0"): 5, t("1_1"): 2}), + ("t_1", {catflt: ["C0"]}, {t("1_0"): 3}), + ("t_1", {catflt: ["C0", "C1"]}, {t("1_0"): 4}), # regions - (regname, {t1filter: t("1_1")}, {"R1": 1}), - (regname, {t1filter: t("1_1"), "key": ["R0", "R1"]}, {"R1": 1, "R0": None}), - (regname, {t1filter: t("1_1"), "key": ["R0"]}, {"R0": None}), + (regname, {t1flt: t("1_0")}, {"R0": 2, "R1": 3, "R2": 3}), + (regname, {t1flt: t("1_1")}, {"R1": 1, "R2": 3}), + (regname, {t1flt: [t("1_1"), t("1_0")]}, {"R0": 2, "R1": 3, "R2": 4}), + (regname, {t1flt: t("1_1"), "key": ["R0", "R1"]}, {"R1": 1, "R0": None}), + (regname, {t1flt: t("1_1"), "key": ["R0"]}, {"R0": None}), # category - (catname, {t1filter: t("1_0")}, {"C0": 3, "C1": 1}), - (catname, {t1filter: t("1_0"), "key": ["C0", "C2"]}, {"C0": 3, "C2": None}), - (catname, {kwfilter: "K1"}, {"C0": 1}), - (catname, {kwfilter: "K1", "key": ["C0", "C2"]}, {"C0": 1, "C2": None}), + (catname, {t1flt: t("1_0")}, {"C0": 3, "C1": 1, "C3": 3}), + (catname, {t1flt: t("1_0"), "key": ["C0", "C2"]}, {"C0": 3, "C2": None}), + (catname, {t1flt: [t("1_0"), t("1_1")]}, {"C0": 3, "C1": 1, "C3": 4}), + (catname, {kwflt: "K1"}, {"C0": 1}), + (catname, {kwflt: "K1", "key": ["C0", "C2"]}, {"C0": 1, "C2": None}), # keyword - (kwname, {t0filter: t("0_0")}, {"K0": 2, "K1": 1, "K2": 1}), - (kwname, {t0filter: t("0_0"), regfilter: "R0"}, {"K1": 1}), - (kwname, {t0filter: t("0_0"), regfilter: "R0", "key": ["K0"]}, {"K0": None}), + (kwname, {t0flt: t("0_0")}, {"K0": 2, "K1": 1, "K2": 1, "K3": 2}), + (kwname, {t0flt: t("1_0")}, {"K0": 4, "K1": 2, "K2": 2, "K3": 3}), + (kwname, {t0flt: [t("1_0"), t("1_1")]}, {"K0": 4, "K1": 2, "K2": 2, "K3": 4}), + (kwname, {t0flt: t("0_0"), regflt: "R0"}, {"K1": 1}), + (kwname, {t0flt: t("0_0"), regflt: "R0", "key": ["K0"]}, {"K0": None}), ): req = self.rf.get(reverse("get_facet", args=[facet]), data=params) + req.user = self.admin res: JsonResponse = GetFacetView.as_view()(req, facet) obj = json.loads(res.content) # self.assertEqual(totals, obj["topics"]["total"], f"Bad totals for facet '{facet} and params {params}")