summaryrefslogtreecommitdiff
path: root/jstests/core/query/not/not2.js
blob: 31b2efcfa02eae4979d9fbbe2b1b0dce1d6a5beb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// @tags: [
//   requires_non_retryable_writes,
// ]

(function() {
"use strict";

const coll = db.jstests_not2;
coll.drop();

function check(query, expected) {
    const resultList = coll.find(query).sort({i: 1}).toArray();
    assert.eq(expected.length, resultList.length, query);

    for (let x = 0; x < expected.length; ++x) {
        assert.eq(expected[x], resultList[x].i, query);
    }
}

function fail(query) {
    assert.throws(() => coll.find(query).itcount());
}

function doTest() {
    assert.commandWorked(coll.remove({}));

    assert.commandWorked(coll.insert({i: "a"}));
    assert.commandWorked(coll.insert({i: "b"}));

    // TODO SERVER-12735: We currently do not handle double negatives during query
    // canonicalization.
    fail({i: {$not: {$not: "a"}}});
    check({i: {$not: {$not: {$gt: "a"}}}}, ["b"]);

    fail({i: {$not: "a"}});
    fail({i: {$not: {$ref: "foo"}}});
    fail({i: {$not: {}}});
    check({i: {$gt: "a"}}, ["b"]);
    check({i: {$not: {$gt: "a"}}}, ["a"]);
    check({i: {$not: {$ne: "a"}}}, ["a"]);
    check({i: {$not: {$gte: "b"}}}, ["a"]);
    check({i: {$exists: true}}, ["a", "b"]);
    check({i: {$not: {$exists: true}}}, []);
    check({j: {$not: {$exists: false}}}, []);
    check({j: {$not: {$exists: true}}}, ["a", "b"]);
    check({i: {$not: {$in: ["a"]}}}, ["b"]);
    check({i: {$not: {$in: ["a", "b"]}}}, []);
    check({i: {$not: {$in: ["g"]}}}, ["a", "b"]);
    check({i: {$not: {$nin: ["a"]}}}, ["a"]);
    check({i: {$not: /a/}}, ["b"]);
    check({i: {$not: /(a|b)/}}, []);
    check({i: {$not: /a/, $regex: "a"}}, []);
    check({i: {$not: /aa/}}, ["a", "b"]);
    check({i: {$not: {$regex: "a"}}}, ["b"]);
    check({i: {$not: {$regex: "A", $options: "i"}}}, ["b"]);
    check({i: {$not: {$regex: "[ab]"}}}, []);
    check({i: {$not: {$regex: "^foo"}}}, ["a", "b"]);
    fail({i: {$not: {$options: "a"}}});
    check({i: {$type: 2}}, ["a", "b"]);
    check({i: {$not: {$type: 1}}}, ["a", "b"]);
    check({i: {$not: {$type: 2}}}, []);

    assert.commandWorked(coll.remove({}));
    assert.commandWorked(coll.insert({i: 1}));
    check({i: {$not: {$mod: [5, 1]}}}, []);
    check({i: {$mod: [5, 2]}}, []);
    check({i: {$not: {$mod: [5, 2]}}}, [1]);

    assert.commandWorked(coll.remove({}));
    assert.commandWorked(coll.insert({i: ["a", "b"]}));
    check({i: {$not: {$size: 2}}}, []);
    check({i: {$not: {$size: 3}}}, [["a", "b"]]);
    check({i: {$not: {$gt: "a"}}}, []);
    check({i: {$not: {$gt: "c"}}}, [["a", "b"]]);
    check({i: {$not: {$all: ["a", "b"]}}}, []);
    check({i: {$not: {$all: ["c"]}}}, [["a", "b"]]);

    assert.commandWorked(coll.remove({}));
    assert.commandWorked(coll.insert({i: [{j: "a"}]}));
    assert.commandWorked(coll.insert({i: [{j: "b"}]}));
    check({i: {$not: {$elemMatch: {j: "a"}}}}, [[{j: "b"}]]);
    check({i: {$not: {$elemMatch: {j: "f"}}}}, [[{j: "a"}], [{j: "b"}]]);
}

// Run the test without any index.
doTest();

// Run the test with an index present.
assert.commandWorked(coll.createIndex({i: 1}));
doTest();
}());