From 25a318f0ff0987361675a90756431a3424c67234 Mon Sep 17 00:00:00 2001 From: Byron Guina Date: Mon, 26 Jan 2026 16:22:13 -0600 Subject: [PATCH] feat(hypergraph): use native spaceId/spaceIds/typeIds filters for entities query The gaia API (geobrowser/gaia#293) added efficient native filters for the entities query: spaceId, spaceIds, typeId, and typeIds. These use indexed EXISTS subqueries instead of the previous approach which ran 2 subqueries per row causing O(n) overhead. This change updates findManyPublic to use the new native filters: - spaceId/spaceIds as top-level query arguments instead of inside filter - typeIds as a top-level argument instead of relation-based filtering The entitiesOrderedByProperty query still uses the old approach since it doesn't yet support the native typeIds filter. --- .../hypergraph/src/entity/find-many-public.ts | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/packages/hypergraph/src/entity/find-many-public.ts b/packages/hypergraph/src/entity/find-many-public.ts index d9b22df9..02374439 100644 --- a/packages/hypergraph/src/entity/find-many-public.ts +++ b/packages/hypergraph/src/entity/find-many-public.ts @@ -58,13 +58,6 @@ const buildEntitiesQuery = ( .filter(Boolean) .join(', '); - const orderByArgs = useOrderBy ? 'propertyId: $propertyId\n sortDirection: $sortDirection\n ' : ''; - const entitySpaceFilter = - spaceSelection.mode === 'single' - ? 'spaceIds: {in: [$spaceId]},' - : spaceSelection.mode === 'many' - ? 'spaceIds: {in: $spaceIds},' - : ''; const valuesListFilter = spaceSelection.mode === 'single' ? '(filter: { spaceId: { is: $spaceId } })' @@ -72,11 +65,22 @@ const buildEntitiesQuery = ( ? '(filter: { spaceId: { in: $spaceIds } })' : ''; - return ` + // entitiesOrderedByProperty doesn't support the native typeIds filter yet, + // so we fall back to the relation-based filter for orderBy queries + if (useOrderBy) { + const orderByArgs = 'propertyId: $propertyId\n sortDirection: $sortDirection\n '; + const entitySpaceFilter = + spaceSelection.mode === 'single' + ? 'spaceIds: {in: [$spaceId]},' + : spaceSelection.mode === 'many' + ? 'spaceIds: {in: $spaceIds},' + : ''; + + return ` query ${queryName}(${variableDefinitions}) { entities: ${queryName}( ${orderByArgs}filter: { and: [{ - relations: {some: {typeId: {is: "8f151ba4de204e3c9cb499ddf96f48f1"}, toEntityId: {in: $typeIds}}}, + relations: {some: {typeId: {is: "8f151ba4de204e3c9cb499ddf96f48f1"}, toEntityId: {in: $typeIds}}}, ${entitySpaceFilter} }, $filter]} first: $first @@ -95,6 +99,39 @@ query ${queryName}(${variableDefinitions}) { } ${level1Relations} } +}`; + } + + // For the regular entities query, use the native spaceId/spaceIds and typeIds filters + const spaceArg = + spaceSelection.mode === 'single' + ? 'spaceId: $spaceId' + : spaceSelection.mode === 'many' + ? 'spaceIds: {in: $spaceIds}' + : ''; + + return ` +query ${queryName}(${variableDefinitions}) { + entities: ${queryName}( + ${spaceArg} + typeIds: {in: $typeIds} + filter: $filter + first: $first + offset: $offset + ) { + id + name${spaceIdsSelection} + valuesList${valuesListFilter} { + propertyId + text + boolean + float + datetime + point + schedule + } + ${level1Relations} + } }`; };