feat(search)!: engine- and domain-agnostic query model, Typesense compiler, and GraphQL surface#529
Open
ddeboer wants to merge 10 commits into
Open
feat(search)!: engine- and domain-agnostic query model, Typesense compiler, and GraphQL surface#529ddeboer wants to merge 10 commits into
ddeboer wants to merge 10 commits into
Conversation
…d result types - replace FieldSpec and Projection with one SearchField/SearchSchema model - add SearchQuery, Filter, Sort and the filter-operator semantics - add the SearchEngine port and result types (SearchResult/SearchHit/ResultDocument/Reference) - add physicalFields (the shared fanout convention) and schema selectors - rewrite projectDocument and projectGraph onto the unified model; projection output unchanged - remove FieldSpec, Projection and the discriminated FieldKind (breaking)
… and SearchEngine - buildCollectionSchema derives a Typesense collection from the unified SearchField model - buildSearchParams compiles SearchQuery into Typesense params (filter_by/sort_by/facet_by/query_by) - createTypesenseSearchEngine implements the SearchEngine port: compile, search, reconstruct - resolve reference and reference-facet labels from the sidecar labels collection in one lookup - add a testcontainer integration test and a generator-stability snapshot
- buildSearchSchema builds an executable GraphQLSchema from any SearchSchema at runtime (no codegen) - one generic resolver maps args to SearchQuery, calls the engine, and maps the result back - derive output, where, orderBy and facet types plus nullability from the field model - best-first Accept-Language output ordering; nullable facet label for reference facets - add printSearchSchema for a consumer SDL snapshot, plus a generator-stability snapshot
ae639ea to
66969a2
Compare
- state the decisions directly as the reconciled architecture, not deviations from a draft - remove the deviation/reconcile framing and the deviations-to-reconcile lists - align wording with the stack platform layer
- number fields now project as floats (not truncated like integer) - closes the step-1 gap so an int64-magnitude field mapped to number (Float) indexes
Replace the repo-path breadcrumb with a direct link to the docs site, so the status note points readers at the rendered page rather than a source file path.
… the group companion - Keyed per-type facets object on the GraphQL surface (ValueBucket / RangeBucket), selection-is-the-request with skip-own-filter. - Numeric range facets and an opt-in label cache in the Typesense adapter. - Reconcile ADRs 0003 and 0004 with the implementation. BREAKING CHANGE: remove SearchField.group and its *_group companion field, collection column and query split. Deployments denormalize group tokens into the field values instead, so a group is an ordinary facet value with no engine mechanism.
…@lde/* pins npm ci failed because the lockfile lacked the new @lde/search-api-graphql workspace. Regenerating against npmjs adds it and brings ~24 @lde/* internal deps up to their latest in-range patches; no third-party or duplicate-version changes.
… search-engine test `result.facets` is a `Partial` record, so a facet is `FacetBucket[] | undefined`; guard the two spreads with `?? []` so the `typecheck` target passes (it never ran in CI before the lockfile fix).
…ations Fold the unified-field-model blockquote and the dated Consequences bullet into running text, so the ADR reads as the current design rather than a change log.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Reworks
@lde/searchand@lde/search-typesenseinto a unified, engine- anddomain-agnostic search API, and adds
@lde/search-api-graphql(the new GraphQL surface).@lde/searchand@lde/search-typesensealready existed in the repo; this reworks them(breaking), it does not introduce them. One declarative
SearchSchemadrives projection, theengine collection schema, the query semantics, and the GraphQL surface – so they cannot drift. The domain type (
Dataset,Person, …) and the engine choice (Typesense, …) are the consumer’s, configured at theseams; the libraries never name a domain.
Packages
@lde/search(core) — breakingSearchField/SearchSchemareplaces the projectionFieldSpec/Projectionand the discriminatedFieldKind.SearchQuery/Filter/Sort) and filter-operator semantics.SearchEngineport and logical result types (SearchResult/SearchHit/ResultDocument/Reference/LocalizedValue/FacetBucket).physicalFields(the shared physical-fanout convention) and schema selectors(
searchableFields,facetableFields,filterableFields,sortableFields,outputFields).projectDocument/projectGraphonto the unified model; projection output isunchanged — the guardrail test was ported field-for-field.
FieldSpec,Projection, and the discriminatedFieldKindare removed.@lde/search-typesense(engine adapter) — additivebuildCollectionSchemaderives a Typesense collection from the field model (kind→type, thephysical fanout via
physicalFields, per-locale stemming, required / default-sorting-field).buildSearchParamscompilesSearchQueryinto Typesense params —filter_by/sort_by/facet_by/query_bywith active-locale weighting, grouped-facet OR, and exact membershipfor non-facet fields.
createTypesenseSearchEngineimplements theSearchEngineport end to end: it reconstructslogical documents and resolves reference (and reference-facet) labels from the sidecar
labelscollection in a single lookup.@lde/search-api-graphql(GraphQL surface) — newbuildSearchSchema(schema, { typeName })builds an executableGraphQLSchemaat runtimefrom any
SearchSchema(no codegen, no SDL artifact), served by one generic resolver overany
SearchEngine.where/orderBy/facet inputs, named reference types, and nullability(from
required/array/kind) from the field model; best-firstAccept-Languageoutput ordering; a nullable facet
labelresolved for reference facets only.printSearchSchemafor a consumer-side SDL snapshot guard.Notes
SearchEnginerename (the interface is theport; the Typesense class is the adapter),
size→Float(int64 overflow), thetyped-surface design, and facet labels.
idOnly/inlinereference strategies, theOutputOf<S>typed-surfaceoverlay, and a REST surface.