// This is a test for the query correctness bug described in SERVER-38949. A {$ne: } query // cannot "naively" use an index. That is, it cannot use an index by simply generating bounds for // {$eq: } query and then complementing them. This test checks that the correct results are // returned for this type of query when an index is present. // @tags: [ // requires_non_retryable_writes, // ] (function() { const coll = db.ne_array; coll.drop(); assert.commandWorked(coll.createIndex({a: 1})); assert.commandWorked(coll.insert({_id: 0, a: [1]})); assert.commandWorked(coll.insert({_id: 1, a: [1, 3]})); assert.eq(coll.find({a: {$ne: [1, 3]}}, {_id: 1}).toArray(), [{_id: 0}]); assert.eq(coll.find({a: {$ne: [1]}}, {_id: 1}).toArray(), [{_id: 1}]); assert.eq(coll.find({a: {$not: {$in: [[1]]}}}, {_id: 1}).toArray(), [{_id: 1}]); assert.eq(coll.find({a: {$not: {$in: [[1, 3]]}}}, {_id: 1}).toArray(), [{_id: 0}]); assert.eq(coll.find({a: {$not: {$in: [[1], [1, 3]]}}}, {_id: 1}).toArray(), []); assert.eq(coll.find({a: {$not: {$in: ["scalar value", [1, 3]]}}}, {_id: 1}).toArray(), [{_id: 0}]); // Insert some documents which have nested arrays so we can test $elemMatch value. assert.commandWorked(coll.remove({})); assert.commandWorked(coll.insert({_id: 0, a: [[123]]})); assert.commandWorked(coll.insert({_id: 1, a: [4, 5, [123]]})); assert.commandWorked(coll.insert({_id: 2, a: [7, 8]})); // sort by _id in case we run on a sharded cluster which puts the documents on different // shards (and thus, might return them in any order). assert.eq(coll.find({a: {$elemMatch: {$not: {$eq: [123]}}}}, {_id: 1}).sort({_id: 1}).toArray(), [{_id: 1}, {_id: 2}]); assert.eq(coll.find({a: {$elemMatch: {$not: {$in: [[123]]}}}}, {_id: 1}).sort({_id: 1}).toArray(), [{_id: 1}, {_id: 2}]); assert.eq(coll.find({a: {$not: {$elemMatch: {$eq: [123]}}}}, {_id: 1}).toArray(), [{_id: 2}]); assert.eq(coll.find({a: {$not: {$elemMatch: {$in: [[123]]}}}}, {_id: 1}).toArray(), [{_id: 2}]); // Test $elemMatch object. assert.commandWorked(coll.remove({})); coll.dropIndexes(); assert.commandWorked(coll.createIndex({"a.b": 1})); assert.commandWorked(coll.insert({_id: 0, a: [[123]]})); assert.commandWorked(coll.insert({_id: 1, a: [{b: 123}]})); assert.commandWorked(coll.insert({_id: 2, a: [{b: [4, [123]]}]})); assert.commandWorked(coll.insert({_id: 3, a: [{b: [[123]]}]})); // Remember that $ne with an array will match arrays where _none_ of the elements match. assert.eq(coll.find({a: {$elemMatch: {b: {$ne: [123]}}}}, {_id: 1}).sort({_id: 1}).toArray(), [{_id: 0}, {_id: 1}]); assert.eq( coll.find({a: {$elemMatch: {b: {$not: {$in: [[123]]}}}}}, {_id: 1}).sort({_id: 1}).toArray(), [{_id: 0}, {_id: 1}]); assert.eq(coll.find({a: {$not: {$elemMatch: {b: [123]}}}}, {_id: 1}).sort({_id: 1}).toArray(), [{_id: 0}, {_id: 1}]); assert.eq( coll.find({a: {$not: {$elemMatch: {b: {$in: [[123]]}}}}}, {_id: 1}).sort({_id: 1}).toArray(), [{_id: 0}, {_id: 1}]); })();