@@ -10,14 +10,15 @@ import {
10
10
Session ,
11
11
UnsecuredDto ,
12
12
} from '~/common' ;
13
- import { DtoRepository , UniquenessError } from '~/core/database' ;
13
+ import { DtoRepository , OnIndex , UniquenessError } from '~/core/database' ;
14
14
import {
15
15
ACTIVE ,
16
16
createNode ,
17
17
createProperty ,
18
18
deactivateProperty ,
19
19
defineSorters ,
20
20
filter ,
21
+ FullTextIndex ,
21
22
matchProps ,
22
23
merge ,
23
24
paginate ,
@@ -32,6 +33,7 @@ import {
32
33
SystemAgent ,
33
34
UpdateUser ,
34
35
User ,
36
+ UserFilters ,
35
37
UserListInput ,
36
38
} from './dto' ;
37
39
@@ -224,11 +226,7 @@ export class UserRepository extends DtoRepository<typeof User, [Session | ID]>(
224
226
. query ( )
225
227
. matchNode ( 'node' , 'User' )
226
228
. match ( requestingUser ( session ) )
227
- . apply (
228
- filter . builder ( input . filter ?? { } , {
229
- pinned : filter . isPinned ,
230
- } ) ,
231
- )
229
+ . apply ( userFilters ( input . filter ) )
232
230
. apply ( this . privileges . forUser ( session ) . filterToReadable ( ) )
233
231
. apply ( sortWith ( userSorters , input ) )
234
232
. apply ( paginate ( input , this . hydrate ( session . userId ) ) )
@@ -364,6 +362,36 @@ export class UserRepository extends DtoRepository<typeof User, [Session | ID]>(
364
362
hydrateAsNeo4j ( session : Session | ID ) {
365
363
return this . hydrate ( session ) ;
366
364
}
365
+
366
+ @OnIndex ( 'schema' )
367
+ private async createSchemaIndexes ( ) {
368
+ await this . db . query ( ) . apply ( NameIndex . create ( ) ) . run ( ) ;
369
+ }
367
370
}
368
371
372
+ export const userFilters = filter . define ( ( ) => UserFilters , {
373
+ pinned : filter . isPinned ,
374
+ name : filter . fullText ( {
375
+ index : ( ) => NameIndex ,
376
+ matchToNode : ( q ) =>
377
+ q . match ( [
378
+ node ( 'node' , 'User' ) ,
379
+ relation ( 'out' , '' , undefined , ACTIVE ) ,
380
+ node ( 'match' ) ,
381
+ ] ) ,
382
+ // Treat each word as a separate search term
383
+ // Each word could point to a different node
384
+ // i.e. "first last"
385
+ separateQueryForEachWord : true ,
386
+ minScore : 0.9 ,
387
+ } ) ,
388
+ } ) ;
389
+
369
390
export const userSorters = defineSorters ( User , { } ) ;
391
+
392
+ const NameIndex = FullTextIndex ( {
393
+ indexName : 'UserName' ,
394
+ labels : 'UserName' ,
395
+ properties : 'value' ,
396
+ analyzer : 'standard-folding' ,
397
+ } ) ;
0 commit comments