From e15976382eec4cdf57a4b3709e2f6a507b54ff80 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev Date: Thu, 8 Jan 2026 10:42:34 +0700 Subject: [PATCH] Add hubCountries query and country filter for nodes --- geo_app/schema.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/geo_app/schema.py b/geo_app/schema.py index 80b273d..eb55ac8 100644 --- a/geo_app/schema.py +++ b/geo_app/schema.py @@ -96,11 +96,18 @@ class Query(graphene.ObjectType): limit=graphene.Int(), offset=graphene.Int(), transport_type=graphene.String(), + country=graphene.String(description="Filter by country name"), search=graphene.String(description="Search by node name (case-insensitive)"), ) nodes_count = graphene.Int( transport_type=graphene.String(), - description="Get total count of nodes (with optional transport filter)", + country=graphene.String(description="Filter by country name"), + description="Get total count of nodes (with optional transport/country filter)", + ) + + hub_countries = graphene.List( + graphene.String, + description="List of countries that have logistics hubs", ) nearest_nodes = graphene.List( @@ -272,7 +279,7 @@ class Query(graphene.ObjectType): edges=[EdgeType(**e) for e in edges], ) - def resolve_nodes(self, info, limit=None, offset=None, transport_type=None, search=None): + def resolve_nodes(self, info, limit=None, offset=None, transport_type=None, country=None, search=None): """Get all logistics nodes (without edges for list view).""" db = get_db() @@ -282,6 +289,7 @@ class Query(graphene.ObjectType): FILTER node.node_type == 'logistics' OR node.node_type == null LET types = node.transport_types != null ? node.transport_types : [] FILTER @transport_type == null OR @transport_type IN types + FILTER @country == null OR node.country == @country FILTER @search == null OR CONTAINS(LOWER(node.name), LOWER(@search)) OR CONTAINS(LOWER(node.country), LOWER(@search)) SORT node.name ASC LIMIT @offset, @limit @@ -291,6 +299,7 @@ class Query(graphene.ObjectType): aql, bind_vars={ 'transport_type': transport_type, + 'country': country, 'search': search, 'offset': 0 if offset is None else offset, 'limit': 1000000 if limit is None else limit, @@ -314,19 +323,34 @@ class Query(graphene.ObjectType): logger.info("Returning %d nodes", len(nodes)) return nodes - def resolve_nodes_count(self, info, transport_type=None): + def resolve_nodes_count(self, info, transport_type=None, country=None): db = get_db() aql = """ FOR node IN nodes FILTER node.node_type == 'logistics' OR node.node_type == null LET types = node.transport_types != null ? node.transport_types : [] FILTER @transport_type == null OR @transport_type IN types + FILTER @country == null OR node.country == @country COLLECT WITH COUNT INTO length RETURN length """ - cursor = db.aql.execute(aql, bind_vars={'transport_type': transport_type}) + cursor = db.aql.execute(aql, bind_vars={'transport_type': transport_type, 'country': country}) return next(cursor, 0) + def resolve_hub_countries(self, info): + """Get unique country names from logistics hubs.""" + db = get_db() + aql = """ + FOR node IN nodes + FILTER node.node_type == 'logistics' OR node.node_type == null + FILTER node.country != null + COLLECT country = node.country + SORT country ASC + RETURN country + """ + cursor = db.aql.execute(aql) + return list(cursor) + def resolve_nearest_nodes(self, info, lat, lon, limit=5): """Find nearest logistics nodes to given coordinates.""" db = get_db()