Skip to content

Commit 896ce62

Browse files
committed
fix $nin
1 parent 6dc91ba commit 896ce62

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

index.js

+21-8
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
9999
if (arrayPath) {
100100
return createElementOrArrayQuery(path, op, value, parent, arrayPath, options)
101101
}
102-
switch(op) {
102+
switch (op) {
103103
case '$not':
104104
return '(NOT ' + convert(path, value, undefined, false, options) + ')'
105105
case '$nor': {
@@ -129,9 +129,8 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
129129
// TODO (make sure this handles multiple elements correctly)
130130
case '$elemMatch':
131131
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': {
135134
if (value.length === 0) {
136135
return 'FALSE'
137136
}
@@ -141,15 +140,29 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
141140
const cleanedValue = value.filter((v) => (v !== null && typeof v !== 'undefined'))
142141
let partial = util.pathToText(path, typeof value[0] == 'string') + (op == '$nin' ? ' NOT' : '') + ' IN (' + cleanedValue.map(util.quote).join(', ') + ')'
143142
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)')
145158
}
146159
return partial
147160
}
148161
case '$text': {
149162
const newOp = '~' + (!value['$caseSensitive'] ? '*' : '')
150163
return util.pathToText(path, true) + ' ' + newOp + ' \'' + util.stringEscape(value['$search']) + '\''
151164
}
152-
case '$regex': {
165+
case '$regex': {
153166
var regexOp = '~'
154167
var op2 = ''
155168
if (parent['$options'] && parent['$options'].includes('i')) {
@@ -169,14 +182,14 @@ function convertOp(path, op, value, parent, arrayPaths, options) {
169182
case '$lt':
170183
case '$lte':
171184
case '$ne':
172-
case '$eq': {
185+
case '$eq': {
173186
const isSimpleComparision = (op === '$eq' || op === '$ne')
174187
const pathContainsArrayAccess = path.some((key) => /^\d+$/.test(key))
175188
if (isSimpleComparision && !pathContainsArrayAccess && !options.disableContainmentQuery) {
176189
// create containment query since these can use GIN indexes
177190
// See docs here, https://www.postgresql.org/docs/9.4/datatype-json.html#JSON-INDEXING
178191
const [head, ...tail] = path
179-
return `${op=='$ne' ? 'NOT ' : ''}${head} @> ` + util.pathToObject([...tail, value])
192+
return `${op == '$ne' ? 'NOT ' : ''}${head} @> ` + util.pathToObject([...tail, value])
180193
} else {
181194
var text = util.pathToText(path, typeof value == 'string')
182195
return text + OPS[op] + util.quote(value)

0 commit comments

Comments
 (0)