@@ -144,6 +144,7 @@ import PuddySqlTags from './PuddySqlTags.mjs';
144144 * @property {string[] } [columns] - List of columns to apply the boost on.
145145 * @property {string } [operator='LIKE'] - Operator used in the condition (e.g., '=', 'LIKE').
146146 * @property {string|string[] } [value] - Value to match in the condition.
147+ * @property {boolean } [array=false] - When true, performs matching using `json_each()` for JSON/ARRAY columns instead of text comparison.
147148 * @property {number } [weight=1] - Weight factor to boost results matching the condition.
148149 */
149150
@@ -620,7 +621,7 @@ class PuddySqlQuery {
620621 // Boost
621622 for ( const boost of boostArray ) {
622623 // Validator
623- const { columns, operator = 'LIKE' , value, weight = 1 } = boost ;
624+ const { columns, operator = 'LIKE' , value, weight = 1 , array = false } = boost ;
624625 if ( typeof operator !== 'string' )
625626 throw new Error ( `operator requires an string value. Got: ${ typeof operator } ` ) ;
626627 const opValue = operator . toUpperCase ( ) ;
@@ -643,7 +644,36 @@ class PuddySqlQuery {
643644 if ( ! Array . isArray ( columns ) || columns . some ( ( col ) => typeof col !== 'string' ) )
644645 throw new Error ( `Boost 'columns' must be a string or array of strings. Got: ${ columns } ` ) ;
645646
646- // In mode
647+ // JSON/ARRAY Mode
648+ if ( array === true ) {
649+ if ( Array . isArray ( value ) ) {
650+ const conditions = columns . map ( ( col ) =>
651+ `
652+ EXISTS (
653+ SELECT 1 FROM json_each(${ col } )
654+ WHERE json_each.value IN (${ value . map ( ( v ) => pg . escapeLiteral ( v ) ) . join ( ', ' ) } )
655+ )
656+ ` . trim ( ) ,
657+ ) ;
658+ cases . push ( `WHEN ${ conditions . join ( ' OR ' ) } THEN ${ weight } ` ) ;
659+ } else if ( typeof value === 'string' ) {
660+ const safeVal = pg . escapeLiteral ( value ) ;
661+ const conditions = columns . map ( ( col ) =>
662+ `
663+ EXISTS (
664+ SELECT 1 FROM json_each(${ col } )
665+ WHERE json_each.value = ${ safeVal }
666+ )
667+ ` . trim ( ) ,
668+ ) ;
669+ cases . push ( `WHEN ${ conditions . join ( ' OR ' ) } THEN ${ weight } ` ) ;
670+ } else {
671+ throw new Error ( `'array' mode requires string or array value. Got: ${ typeof value } ` ) ;
672+ }
673+ continue ;
674+ }
675+
676+ // IN Mode
647677 if ( opValue === 'IN' ) {
648678 if ( ! Array . isArray ( value ) )
649679 throw new Error ( `'${ opValue } ' operator requires an array value. Got: ${ typeof value } ` ) ;
@@ -653,19 +683,18 @@ class PuddySqlQuery {
653683 return `${ col } IN (${ inList } )` ;
654684 } ) ;
655685 cases . push ( `WHEN ${ conditions . join ( ' OR ' ) } THEN ${ weight } ` ) ;
686+ continue ;
656687 }
657688
658- // Other modes
659- else {
660- if ( typeof value !== 'string' )
661- throw new Error ( `'${ opValue } ' operator requires an string value. Got: ${ typeof value } ` ) ;
689+ // Other modes (LIKE, =, etc.)
690+ if ( typeof value !== 'string' )
691+ throw new Error ( `'${ opValue } ' operator requires a string value. Got: ${ typeof value } ` ) ;
662692
663- const safeVal = pg . escapeLiteral (
664- [ 'LIKE' , 'ILIKE' ] . includes ( opValue ) ? `%${ value } %` : value ,
665- ) ;
666- const conditions = columns . map ( ( col ) => `${ col } ${ operator } ${ safeVal } ` ) ;
667- cases . push ( `WHEN ${ conditions . join ( ' OR ' ) } THEN ${ weight } ` ) ;
668- }
693+ const safeVal = pg . escapeLiteral (
694+ [ 'LIKE' , 'ILIKE' ] . includes ( opValue ) ? `%${ value } %` : value ,
695+ ) ;
696+ const conditions = columns . map ( ( col ) => `${ col } ${ operator } ${ safeVal } ` ) ;
697+ cases . push ( `WHEN ${ conditions . join ( ' OR ' ) } THEN ${ weight } ` ) ;
669698 }
670699
671700 return `CASE ${ cases . join ( ' ' ) } ELSE 0 END AS ${ alias } ` ;
0 commit comments