Skip to content

Commit d277670

Browse files
committed
rename fullTextSearch composite filter to unifiedSearch
Rename the composite GraphQL filter field from fullTextSearch to unifiedSearch across the plugin, codegen, tests, and skills to disambiguate it from the tsvector-specific fullTextSearchTsv filter. - Plugin: rename field, config option enableFullTextSearch → enableUnifiedSearch - Codegen: update CLI example docs in docs-utils.ts - Tests: update all GraphQL queries and assertions - Skills: update CLI examples in user.md references The full_text_search metaschema DB table and tsvector adapter naming (fullTextSearchTsv, filterPrefix) are intentionally left unchanged.
1 parent 2128d45 commit d277670

10 files changed

Lines changed: 82 additions & 82 deletions

File tree

.agents/skills/cli-auth/references/user.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ csdk user list --where.searchTsv "search query" --select title,tsvRank
7171
csdk user list --where.trgmDisplayName.value "approximate query" --where.trgmDisplayName.threshold 0.3 --select title,displayNameTrgmSimilarity
7272
```
7373

74-
### Composite search (fullTextSearch dispatches to all text adapters)
74+
### Composite search (unifiedSearch dispatches to all text adapters)
7575

7676
```bash
77-
csdk user list --where.fullTextSearch "search query" --select title,tsvRank,displayNameTrgmSimilarity,searchScore
77+
csdk user list --where.unifiedSearch "search query" --select title,tsvRank,displayNameTrgmSimilarity,searchScore
7878
```
7979

8080
### Search with pagination and field projection
8181

8282
```bash
83-
csdk user list --where.fullTextSearch "query" --limit 10 --select id,title,searchScore
83+
csdk user list --where.unifiedSearch "query" --limit 10 --select id,title,searchScore
8484
csdk user search "query" --limit 10 --select id,title,searchScore
8585
```
8686

.agents/skills/cli-public/references/user.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ csdk user list --where.searchTsv "search query" --select title,tsvRank
7171
csdk user list --where.trgmDisplayName.value "approximate query" --where.trgmDisplayName.threshold 0.3 --select title,displayNameTrgmSimilarity
7272
```
7373

74-
### Composite search (fullTextSearch dispatches to all text adapters)
74+
### Composite search (unifiedSearch dispatches to all text adapters)
7575

7676
```bash
77-
csdk user list --where.fullTextSearch "search query" --select title,tsvRank,displayNameTrgmSimilarity,searchScore
77+
csdk user list --where.unifiedSearch "search query" --select title,tsvRank,displayNameTrgmSimilarity,searchScore
7878
```
7979

8080
### Search with pagination and field projection
8181

8282
```bash
83-
csdk user list --where.fullTextSearch "query" --limit 10 --select id,title,searchScore
83+
csdk user list --where.unifiedSearch "query" --limit 10 --select id,title,searchScore
8484
csdk user search "query" --limit 10 --select id,title,searchScore
8585
```
8686

graphile/graphile-search/src/__tests__/search-config-integration.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ describe('@searchConfig integration tests', () => {
113113
createPgvectorAdapter(),
114114
],
115115
enableSearchScore: true,
116-
enableFullTextSearch: true,
116+
enableUnifiedSearch: true,
117117
});
118118

119119
// Inject @searchConfig on the articles table with custom weights
@@ -289,7 +289,7 @@ describe('@searchConfig with sigmoid normalization', () => {
289289
createPgvectorAdapter(),
290290
],
291291
enableSearchScore: true,
292-
enableFullTextSearch: true,
292+
enableUnifiedSearch: true,
293293
});
294294

295295
// Inject @searchConfig with sigmoid normalization

graphile/graphile-search/src/__tests__/unified-search.test.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('graphile-search (unified search plugin)', () => {
5858
createPgvectorAdapter(),
5959
],
6060
enableSearchScore: true,
61-
enableFullTextSearch: true,
61+
enableUnifiedSearch: true,
6262
});
6363

6464
const testPreset = {
@@ -585,16 +585,16 @@ describe('graphile-search (unified search plugin)', () => {
585585
expect(limitNodes[1].rowId).toBe(allNodes[1].rowId);
586586
});
587587

588-
it('fullTextSearch + per-adapter orderBy: LIMIT returns top results', async () => {
589-
// fullTextSearch dispatches to all text-compatible adapters.
588+
it('unifiedSearch + per-adapter orderBy: LIMIT returns top results', async () => {
589+
// unifiedSearch dispatches to all text-compatible adapters.
590590
// Per-adapter orderBy (e.g. BM25 score) still works correctly with LIMIT
591591
// because the adapter score is a SQL-level expression.
592592
// (Note: SEARCH_SCORE is a JS-computed composite and does not produce
593593
// SQL-level ORDER BY, so it should not be relied on with LIMIT.)
594594
const allResult = await query<AllDocumentsResult>(`
595595
query {
596596
allDocuments(
597-
where: { fullTextSearch: "machine learning" }
597+
where: { unifiedSearch: "machine learning" }
598598
orderBy: BODY_BM25_SCORE_ASC
599599
) {
600600
nodes { rowId title bodyBm25Score }
@@ -609,7 +609,7 @@ describe('graphile-search (unified search plugin)', () => {
609609
const limitResult = await query<AllDocumentsResult>(`
610610
query {
611611
allDocuments(
612-
where: { fullTextSearch: "machine learning" }
612+
where: { unifiedSearch: "machine learning" }
613613
orderBy: BODY_BM25_SCORE_ASC
614614
first: 1
615615
) {
@@ -732,18 +732,18 @@ describe('graphile-search (unified search plugin)', () => {
732732
}
733733
});
734734

735-
it('mega query v2: fullTextSearch + searchScore with composite ordering', async () => {
736-
// Mega Query v2 — New-style: uses the unified `fullTextSearch` composite
735+
it('mega query v2: unifiedSearch + searchScore with composite ordering', async () => {
736+
// Mega Query v2 — New-style: uses the unified `unifiedSearch` composite
737737
// filter that fans out to all text-compatible algorithms (tsvector, BM25, trgm)
738738
// with a single string, plus a manual pgvector filter for semantic search.
739739
// Orders by composite searchScore (highest overall relevance first).
740740
const result = await query<AllDocumentsResult>(`
741741
query MegaQueryV2_UnifiedSearch {
742742
allDocuments(
743743
where: {
744-
# fullTextSearch: single string fans out to tsvector + BM25 + trgm
744+
# unifiedSearch: single string fans out to tsvector + BM25 + trgm
745745
# automatically — no need to specify each algorithm separately
746-
fullTextSearch: "machine learning"
746+
unifiedSearch: "machine learning"
747747
748748
# pgvector still needs its own filter (vectors aren't text)
749749
vectorEmbedding: { vector: [1, 0, 0], metric: COSINE }
@@ -757,7 +757,7 @@ describe('graphile-search (unified search plugin)', () => {
757757
title
758758
body
759759
760-
# Per-adapter scores — populated by fullTextSearch for text algorithms
760+
# Per-adapter scores — populated by unifiedSearch for text algorithms
761761
tsvRank
762762
bodyBm25Score
763763
titleTrgmSimilarity
@@ -788,14 +788,14 @@ describe('graphile-search (unified search plugin)', () => {
788788
});
789789
});
790790

791-
// ─── fullTextSearch composite filter ────────────────────────────────────
791+
// ─── unifiedSearch composite filter ────────────────────────────────────
792792

793-
describe('fullTextSearch composite filter', () => {
794-
it('fullTextSearch field exists on the filter type', async () => {
793+
describe('unifiedSearch composite filter', () => {
794+
it('unifiedSearch field exists on the filter type', async () => {
795795
const result = await query<AllDocumentsResult>(`
796796
query {
797797
allDocuments(where: {
798-
fullTextSearch: "learning"
798+
unifiedSearch: "learning"
799799
}) {
800800
nodes {
801801
title
@@ -813,7 +813,7 @@ describe('graphile-search (unified search plugin)', () => {
813813
const result = await query<AllDocumentsResult>(`
814814
query {
815815
allDocuments(where: {
816-
fullTextSearch: "machine learning"
816+
unifiedSearch: "machine learning"
817817
}) {
818818
nodes {
819819
title
@@ -843,7 +843,7 @@ describe('graphile-search (unified search plugin)', () => {
843843
const result = await query<AllDocumentsResult>(`
844844
query {
845845
allDocuments(where: {
846-
fullTextSearch: "learning"
846+
unifiedSearch: "learning"
847847
tsvTsv: "machine"
848848
}) {
849849
nodes {
@@ -856,15 +856,15 @@ describe('graphile-search (unified search plugin)', () => {
856856

857857
expect(result.errors).toBeUndefined();
858858
const nodes = result.data?.allDocuments?.nodes ?? [];
859-
// The algorithm-specific filter (tsvTsv) narrows further within the fullTextSearch results
859+
// The algorithm-specific filter (tsvTsv) narrows further within the unifiedSearch results
860860
expect(nodes).toBeDefined();
861861
});
862862

863863
it('returns empty results for nonsense query', async () => {
864864
const result = await query<AllDocumentsResult>(`
865865
query {
866866
allDocuments(where: {
867-
fullTextSearch: "xyzzy_nonexistent_term_12345"
867+
unifiedSearch: "xyzzy_nonexistent_term_12345"
868868
}) {
869869
nodes {
870870
title
@@ -908,22 +908,22 @@ describe('graphile-search (unified search plugin)', () => {
908908
});
909909
});
910910

911-
// ─── fullTextSearch disabled (separate suite — needs its own DB connection) ───
911+
// ─── unifiedSearch disabled (separate suite — needs its own DB connection) ───
912912

913-
describe('fullTextSearch can be disabled', () => {
913+
describe('unifiedSearch can be disabled', () => {
914914
let disabledQuery: QueryFn;
915915
let disabledTeardown: (() => Promise<void>) | undefined;
916916

917917
beforeAll(async () => {
918-
// Build a plugin with fullTextSearch DISABLED
918+
// Build a plugin with unifiedSearch DISABLED
919919
const disabledPlugin = createUnifiedSearchPlugin({
920920
adapters: [
921921
createTsvectorAdapter(),
922922
createBm25Adapter(),
923923
createTrgmAdapter({ defaultThreshold: 0.1 }),
924924
],
925925
enableSearchScore: true,
926-
enableFullTextSearch: false,
926+
enableUnifiedSearch: false,
927927
});
928928

929929
const disabledPreset = {
@@ -956,8 +956,8 @@ describe('fullTextSearch can be disabled', () => {
956956
}
957957
});
958958

959-
it('fullTextSearch field does NOT exist when disabled', async () => {
960-
// Introspect the filter type to verify fullTextSearch is NOT present.
959+
it('unifiedSearch field does NOT exist when disabled', async () => {
960+
// Introspect the filter type to verify unifiedSearch is NOT present.
961961
// NOTE: Grafast silently ignores unknown input fields rather than
962962
// returning a GraphQL validation error, so we verify via introspection.
963963
const introspection = await disabledQuery<any>(`
@@ -973,10 +973,10 @@ describe('fullTextSearch can be disabled', () => {
973973
expect(introspection.errors).toBeUndefined();
974974
const filterFields = introspection.data?.__type?.inputFields?.map((f: any) => f.name) ?? [];
975975

976-
// fullTextSearch should NOT be in the filter fields
977-
expect(filterFields).not.toContain('fullTextSearch');
976+
// unifiedSearch should NOT be in the filter fields
977+
expect(filterFields).not.toContain('unifiedSearch');
978978

979-
// The per-algorithm fields should still exist (only fullTextSearch is disabled)
979+
// The per-algorithm fields should still exist (only unifiedSearch is disabled)
980980
expect(filterFields).toContain('tsvTsv');
981981
expect(filterFields).toContain('bm25Body');
982982
expect(filterFields).toContain('trgmTitle');

graphile/graphile-search/src/plugin.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ interface AdapterColumnCache {
177177
export function createUnifiedSearchPlugin(
178178
options: UnifiedSearchOptions
179179
): GraphileConfig.Plugin {
180-
const { adapters, enableSearchScore = true, enableFullTextSearch = true } = options;
180+
const { adapters, enableSearchScore = true, enableUnifiedSearch = true } = options;
181181

182182
// Per-codec cache of discovered columns, keyed by codec name
183183
const codecCache = new Map<string, AdapterColumnCache[]>();
@@ -857,18 +857,18 @@ export function createUnifiedSearchPlugin(
857857
}
858858
}
859859

860-
// ── fullTextSearch composite filter ──
861-
// Adds a single `fullTextSearch: String` field that fans out the same
860+
// ── unifiedSearch composite filter ──
861+
// Adds a single `unifiedSearch: String` field that fans out the same
862862
// text query to all adapters where supportsTextSearch is true.
863863
// WHERE clauses are combined with OR (match ANY algorithm).
864-
if (enableFullTextSearch) {
864+
if (enableUnifiedSearch) {
865865
// Collect text-compatible adapters and their columns for this codec
866866
const textAdapterColumns = adapterColumns.filter(
867867
(ac) => ac.adapter.supportsTextSearch && ac.adapter.buildTextSearchInput
868868
);
869869

870870
if (textAdapterColumns.length > 0) {
871-
const fieldName = 'fullTextSearch';
871+
const fieldName = 'unifiedSearch';
872872

873873
newFields = build.extend(
874874
newFields,
@@ -880,7 +880,7 @@ export function createUnifiedSearchPlugin(
880880
} as any,
881881
{
882882
description: build.wrapDescription(
883-
'Composite full-text search. Provide a search string and it will be dispatched ' +
883+
'Composite unified search. Provide a search string and it will be dispatched ' +
884884
'to all text-compatible search algorithms (tsvector, BM25, pg_trgm) simultaneously. ' +
885885
'Rows matching ANY algorithm are returned. All matching score fields are populated.',
886886
'field'
@@ -956,7 +956,7 @@ export function createUnifiedSearchPlugin(
956956
}
957957
),
958958
},
959-
`UnifiedSearchPlugin adding fullTextSearch composite filter on '${codec.name}'`
959+
`UnifiedSearchPlugin adding unifiedSearch composite filter on '${codec.name}'`
960960
);
961961
}
962962
}

graphile/graphile-search/src/preset.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ export interface UnifiedSearchPresetOptions {
6868
enableSearchScore?: boolean;
6969

7070
/**
71-
* Whether to expose the composite `fullTextSearch` filter field.
71+
* Whether to expose the composite `unifiedSearch` filter field.
7272
* @default true
7373
*/
74-
enableFullTextSearch?: boolean;
74+
enableUnifiedSearch?: boolean;
7575

7676
/**
7777
* Custom weights for the composite searchScore.
@@ -105,7 +105,7 @@ export function UnifiedSearchPreset(
105105
trgm = true,
106106
pgvector = true,
107107
enableSearchScore = true,
108-
enableFullTextSearch = true,
108+
enableUnifiedSearch = true,
109109
searchScoreWeights,
110110
fullTextScalarName = 'FullText',
111111
tsConfig = 'english',
@@ -136,7 +136,7 @@ export function UnifiedSearchPreset(
136136
const pluginOptions: UnifiedSearchOptions = {
137137
adapters,
138138
enableSearchScore,
139-
enableFullTextSearch,
139+
enableUnifiedSearch,
140140
searchScoreWeights,
141141
};
142142

graphile/graphile-search/src/types.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export interface SearchAdapter {
114114
/**
115115
* Whether this adapter supports plain text search queries.
116116
* If true, the adapter's columns will be included in the automatic
117-
* `fullTextSearch` composite filter that fans out the same text query
117+
* `unifiedSearch` composite filter that fans out the same text query
118118
* to all text-compatible adapters simultaneously.
119119
*
120120
* Adapters that require non-text input (e.g. pgvector needs a vector array)
@@ -125,7 +125,7 @@ export interface SearchAdapter {
125125
supportsTextSearch?: boolean;
126126

127127
/**
128-
* Build the filter value for a text search query dispatched by fullTextSearch.
128+
* Build the filter value for a text search query dispatched by unifiedSearch.
129129
* Only called when supportsTextSearch is true.
130130
* Converts a plain text string into the adapter-specific filter input format.
131131
*
@@ -209,14 +209,14 @@ export interface UnifiedSearchOptions {
209209
enableSearchScore?: boolean;
210210

211211
/**
212-
* Whether to expose the `fullTextSearch` composite filter field.
212+
* Whether to expose the `unifiedSearch` composite filter field.
213213
* When enabled, every table with at least one text-compatible adapter gets a
214-
* `fullTextSearch: String` field on its filter type. Providing a value fans
214+
* `unifiedSearch: String` field on its filter type. Providing a value fans
215215
* out the same text query to all adapters where `supportsTextSearch: true`,
216216
* combining their WHERE clauses with OR (match any algorithm).
217217
* @default true
218218
*/
219-
enableFullTextSearch?: boolean;
219+
enableUnifiedSearch?: boolean;
220220

221221
/**
222222
* Custom weights for the composite searchScore. Keys are adapter names,

graphql/codegen/src/core/codegen/docs-utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ export function buildSearchExamples(
393393
}
394394
}
395395

396-
// Composite fullTextSearch example (dispatches to all text adapters)
396+
// Composite unifiedSearch example (dispatches to all text adapters)
397397
const hasTextSearch = specialGroups.some(
398398
(g) => g.category === 'search' && g.fields.some(
399399
(f) => f.type.gqlType === 'FullText' || /TrgmSimilarity$/.test(f.name) || /Bm25Score$/.test(f.name),
@@ -404,9 +404,9 @@ export function buildSearchExamples(
404404
? `title,${[...new Set(scoreFields)].join(',')}`
405405
: 'title';
406406
examples.push({
407-
description: 'Composite search (fullTextSearch dispatches to all text adapters)',
407+
description: 'Composite search (unifiedSearch dispatches to all text adapters)',
408408
code: [
409-
`${toolName} ${cmd} list --where.fullTextSearch "search query" --select ${fieldsArg}`,
409+
`${toolName} ${cmd} list --where.unifiedSearch "search query" --select ${fieldsArg}`,
410410
],
411411
});
412412
}
@@ -416,7 +416,7 @@ export function buildSearchExamples(
416416
examples.push({
417417
description: 'Search with pagination and field projection',
418418
code: [
419-
`${toolName} ${cmd} list --where.fullTextSearch "query" --limit 10 --select id,title,searchScore`,
419+
`${toolName} ${cmd} list --where.unifiedSearch "query" --limit 10 --select id,title,searchScore`,
420420
`${toolName} ${cmd} search "query" --limit 10 --select id,title,searchScore`,
421421
],
422422
});

0 commit comments

Comments
 (0)