Skip to content

Facet a canonically keyed type by the datasets that reference it #790

Description

@ddeboer

Since #785, a canonically keyed collection records which datasets reference each document, in a private referenced_by: [{ dataset, run }]. That column holds the answer to a question consumers can currently ask of no keyed type: which datasets reference this term – and its inverse, show me the Getty terms this publisher uses.

It is also the honest version of a question ADR 25 had to forbid. A keyed type may not declare a from: 'dataset' field, because on a shared document that field would hold whichever dataset wrote last and a filter on any of the others would silently miss it. referenced_by has no such problem: it is the whole set, and it is correct by construction.

What is already true

Nothing about the engine or the stored data needs to change. referenced_by.dataset is declared facet: true, and test/membership-filters.integration.test.ts pins both halves against a real Typesense:

  • facet_by=referenced_by.dataset returns one bucket per referring dataset;
  • referenced_by.dataset:=[A,C] filters by containment.

What is missing is only the declaration a deployment writes and the surface it produces. Responses are assembled from outputFields(searchType), so today the column is invisible by design.

The crux: a field whose values come from bookkeeping

This would be the first declared field whose values come from the writer rather than from the graph.

Every field today is projection-populated; from: 'dataset' is filled by the projection and merely reasserted by the writer, which is why the writer's stamp “only ever reasserts it”. Membership has no projection source at all – the writer is the only thing that writes it, and the projection must never touch it. So the design question is how @lde/search expresses that category, and what a deployment writes to opt in. Worth settling before any code: it is a new kind of field, not a new field.

Naming should stay in the voice ADR 25 establishedwhich datasets reference this document, plural – and never dataset, singular, which is the conflation the ADR removed.

Scope

In: faceting and filtering a keyed type by its referring datasets, with label resolution through the existing lookup strategy (the stored values are dataset IRIs, which are ids in the datasets collection – ADR 20 already covers this).

Out (for a first cut): a joinable membership reference. Typesense carries reference: on top-level fields only (collection-definition.ts:226), so cross-collection filtering through membership would need a flat companion beside the nested column – the identity-companion pattern inline references already use (${name}_id, plus a narrowed ${name}_facet where the target declares a facetKeys policy). Known move, but it earns its own issue if a consumer asks for it.

Unaffected: the sweep. maxSweepableSources faceting is the writer's own bookkeeping and is untouched by anything a query does.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions