Skip to content

Commit 11ffadc

Browse files
committed
Add filter builder for full text search
1 parent 1781654 commit 11ffadc

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

src/core/database/query/filters.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { Comparator } from 'cypher-query-builder/dist/typings/clauses/where-comp
1414
import { identity, isFunction } from 'lodash';
1515
import { AbstractClass, ConditionalKeys } from 'type-fest';
1616
import { DateTimeFilter } from '~/common';
17+
import { collect } from './cypher-functions';
18+
import { escapeLuceneSyntax, FullTextIndex } from './full-text';
1719
import { ACTIVE } from './matching';
1820
import { WhereAndList } from './where-and-list';
1921
import { path as pathPattern } from './where-path';
@@ -232,3 +234,35 @@ export const sub =
232234
.return(`true as ${key}FiltersApplied`),
233235
)
234236
.with('*');
237+
238+
export const fullText =
239+
({
240+
index,
241+
matchToNode,
242+
}: {
243+
index: () => FullTextIndex;
244+
matchToNode: (query: Query) => Query;
245+
}) =>
246+
<T, K extends ConditionalKeys<T, string | undefined>>({
247+
value: input,
248+
key: field,
249+
query,
250+
}: BuilderArgs<T, K>) => {
251+
if (!input || typeof input !== 'string') {
252+
return null;
253+
}
254+
const escaped = escapeLuceneSyntax(input);
255+
256+
const lucene = `*${escaped}*`;
257+
258+
query
259+
.subQuery((q) =>
260+
q
261+
.call(index().search(lucene, { limit: 100 }).yield({ node: 'match' }))
262+
.apply(matchToNode)
263+
.return(collect('distinct node').as(`${field}Matches`)),
264+
)
265+
.with('*');
266+
267+
return { node: inArray(`${field}Matches`, true) };
268+
};

src/core/database/query/full-text.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { procedure } from '../query-augmentation/call';
66
import { CypherExpression, exp, isExp } from './cypher-expression';
77
import { db } from './cypher-functions';
88

9+
export type FullTextIndex = ReturnType<typeof FullTextIndex>;
10+
911
/**
1012
* @see https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/
1113
*/

0 commit comments

Comments
 (0)