@@ -99,7 +99,7 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
99
99
if ( arrayPath ) {
100
100
return createElementOrArrayQuery ( path , op , value , parent , arrayPath , options )
101
101
}
102
- switch ( op ) {
102
+ switch ( op ) {
103
103
case '$not' :
104
104
return '(NOT ' + convert ( path , value , undefined , false , options ) + ')'
105
105
case '$nor' : {
@@ -129,9 +129,8 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
129
129
// TODO (make sure this handles multiple elements correctly)
130
130
case '$elemMatch' :
131
131
return convert ( path , value , arrayPaths , false , options )
132
- //return util.pathToText(path, false) + ' @> \'' + util.stringEscape(JSON.stringify(value)) + '\'::jsonb'
133
- case '$in' :
134
- case '$nin' : {
132
+ //return util.pathToText(path, false) + ' @> \'' + util.stringEscape(JSON.stringify(value)) + '\'::jsonb'
133
+ case '$in' : {
135
134
if ( value . length === 0 ) {
136
135
return 'FALSE'
137
136
}
@@ -141,15 +140,29 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
141
140
const cleanedValue = value . filter ( ( v ) => ( v !== null && typeof v !== 'undefined' ) )
142
141
let partial = util . pathToText ( path , typeof value [ 0 ] == 'string' ) + ( op == '$nin' ? ' NOT' : '' ) + ' IN (' + cleanedValue . map ( util . quote ) . join ( ', ' ) + ')'
143
142
if ( value . length != cleanedValue . length ) {
144
- return ( op === '$in' ? '(' + partial + ' OR IS NULL)' : '(' + partial + ' AND IS NOT NULL)' )
143
+ return ( op === '$in' ? '(' + partial + ' OR IS NULL)' : '(' + partial + ' AND IS NOT NULL)' )
144
+ }
145
+ return partial
146
+ }
147
+ case '$nin' : {
148
+ /* if (value.length === 0) {
149
+ return 'FALSE'
150
+ }
151
+ if (value.length === 1) {
152
+ return convert(path, value[0], arrayPaths, false, options)
153
+ } */
154
+ const cleanedValue = value . filter ( ( v ) => ( v !== null && typeof v !== 'undefined' ) )
155
+ let partial = util . pathToText ( path , typeof value [ 0 ] == 'string' ) + ( op == '$nin' ? ' NOT' : '' ) + ' IN (' + cleanedValue . map ( util . quote ) . join ( ', ' ) + ')'
156
+ if ( value . length != cleanedValue . length ) {
157
+ return ( op === '$in' ? '(' + partial + ' OR IS NULL)' : '(' + partial + ' AND IS NOT NULL)' )
145
158
}
146
159
return partial
147
160
}
148
161
case '$text' : {
149
162
const newOp = '~' + ( ! value [ '$caseSensitive' ] ? '*' : '' )
150
163
return util . pathToText ( path , true ) + ' ' + newOp + ' \'' + util . stringEscape ( value [ '$search' ] ) + '\''
151
164
}
152
- case '$regex' : {
165
+ case '$regex' : {
153
166
var regexOp = '~'
154
167
var op2 = ''
155
168
if ( parent [ '$options' ] && parent [ '$options' ] . includes ( 'i' ) ) {
@@ -169,14 +182,14 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
169
182
case '$lt' :
170
183
case '$lte' :
171
184
case '$ne' :
172
- case '$eq' : {
185
+ case '$eq' : {
173
186
const isSimpleComparision = ( op === '$eq' || op === '$ne' )
174
187
const pathContainsArrayAccess = path . some ( ( key ) => / ^ \d + $ / . test ( key ) )
175
188
if ( isSimpleComparision && ! pathContainsArrayAccess && ! options . disableContainmentQuery ) {
176
189
// create containment query since these can use GIN indexes
177
190
// See docs here, https://www.postgresql.org/docs/9.4/datatype-json.html#JSON-INDEXING
178
191
const [ head , ...tail ] = path
179
- return `${ op == '$ne' ? 'NOT ' : '' } ${ head } @> ` + util . pathToObject ( [ ...tail , value ] )
192
+ return `${ op == '$ne' ? 'NOT ' : '' } ${ head } @> ` + util . pathToObject ( [ ...tail , value ] )
180
193
} else {
181
194
var text = util . pathToText ( path , typeof value == 'string' )
182
195
return text + OPS [ op ] + util . quote ( value )
0 commit comments