Skip to content

Commit dc0114f

Browse files
authored
Merge pull request #956 from constructive-io/devin/1775105159-rename-fullTextSearch-to-unifiedSearch
Rename `fullTextSearch` composite filter to `unifiedSearch`
2 parents 2128d45 + d277670 commit dc0114f

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)