@@ -114,6 +114,18 @@ export async function vectorSearchWithDrizzle(
114114 return rows . map ( ( row ) => rowToContext ( row ) )
115115}
116116
117+ /** JSONB overlap (row has any of these doc group names). Use @> containment since && is not supported for jsonb in PostgreSQL. */
118+ function docGroupsOverlapCondition ( table : typeof embeddings , names : string [ ] ) {
119+ if ( names . length === 0 ) return undefined
120+ if ( names . length === 1 )
121+ return sql `(${ table . doc_groups } @> ${ JSON . stringify ( [ names [ 0 ] ] ) } ::jsonb)`
122+ return or (
123+ ...names . map (
124+ ( n ) => sql `(${ table . doc_groups } @> ${ JSON . stringify ( [ n ] ) } ::jsonb)` ,
125+ ) ,
126+ ) !
127+ }
128+
117129function buildShouldCondition (
118130 table : typeof embeddings ,
119131 course_name : string ,
@@ -124,7 +136,7 @@ function buildShouldCondition(
124136 doc_groups . length > 0 && ! doc_groups . includes ( 'All Documents' )
125137 ? and (
126138 eq ( table . course_name , course_name ) ,
127- sql ` ${ table . doc_groups } && ${ JSON . stringify ( doc_groups ) } ::jsonb` ,
139+ docGroupsOverlapCondition ( table , doc_groups ) ,
128140 )
129141 : eq ( table . course_name , course_name )
130142
@@ -133,7 +145,7 @@ function buildShouldCondition(
133145 . map ( ( p ) =>
134146 and (
135147 eq ( table . course_name , p . course_name ) ,
136- sql ` ${ table . doc_groups } && ${ JSON . stringify ( [ p . name ] ) } ::jsonb` ,
148+ docGroupsOverlapCondition ( table , [ p . name ] ) ,
137149 ) ,
138150 )
139151
@@ -146,7 +158,9 @@ function buildMustNotCondition(
146158 disabled_doc_groups : string [ ] ,
147159) {
148160 if ( disabled_doc_groups . length === 0 ) return undefined
149- return sql `NOT (${ table . doc_groups } && ${ JSON . stringify ( disabled_doc_groups ) } ::jsonb)`
161+ const overlap = docGroupsOverlapCondition ( table , disabled_doc_groups )
162+ if ( ! overlap ) return undefined
163+ return sql `NOT (${ overlap } )`
150164}
151165
152166function rowToContext ( row : {
0 commit comments