summaryrefslogtreecommitdiff
path: root/jstests/core/wildcard_index_equality_to_empty_obj.js
blob: 28e9953414797c03c1b53f35695ec246e7388220 (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
/**
 * Tests that a $** index can support queries which test for equality to empty nested objects.
 */
(function() {
    "use strict";

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

    assert.commandWorked(coll.insert([
        {_id: 0},
        {_id: 1, a: null},
        {_id: 2, a: []},
        {_id: 3, a: {}},
        {_id: 4, a: [{}]},
        {_id: 5, a: [[{}]]},
        {_id: 6, a: [1, 2, {}]},
        {_id: 7, a: {b: 1}},
        {_id: 8, a: 3},
        {_id: 9, a: {b: {}}},
        {_id: 10, a: [0, {b: {}}]},
    ]));

    assert.commandWorked(coll.createIndex({"$**": 1}));

    // Test that a comparison to empty object query returns the expected results when the $** index
    // is hinted.
    let results = coll.find({a: {}}, {_id: 1}).sort({_id: 1}).hint({"$**": 1}).toArray();
    assert.eq(results, [{_id: 3}, {_id: 4}, {_id: 6}]);

    // Result set should be the same as when hinting a COLLSCAN and with no hint.
    assert.eq(results, coll.find({a: {}}, {_id: 1}).sort({_id: 1}).hint({$natural: 1}).toArray());
    assert.eq(results, coll.find({a: {}}, {_id: 1}).sort({_id: 1}).toArray());

    // Repeat the above query, but express it using $lte:{}, which is a synonym for $eq:{}.
    results = coll.find({a: {$lte: {}}}, {_id: 1}).sort({_id: 1}).hint({"$**": 1}).toArray();
    assert.eq(results, [{_id: 3}, {_id: 4}, {_id: 6}]);
    assert.eq(results,
              coll.find({a: {$lte: {}}}, {_id: 1}).sort({_id: 1}).hint({$natural: 1}).toArray());
    assert.eq(results, coll.find({a: {$lte: {}}}, {_id: 1}).sort({_id: 1}).toArray());

    // Test that an inequality to empty object query results in an error when the $** index is
    // hinted.
    assert.throws(
        () => coll.find({a: {$gte: {}}}, {_id: 1}).sort({_id: 1}).hint({"$**": 1}).toArray());

    // Test that an inequality to empty object query returns the expected results in the presence of
    // the $** index.
    results = coll.find({a: {$gte: {}}}, {_id: 1}).sort({_id: 1}).toArray();
    assert.eq(results, [{_id: 3}, {_id: 4}, {_id: 6}, {_id: 7}, {_id: 9}, {_id: 10}]);

    // Result set should be the same as when hinting a COLLSCAN and with no hint.
    assert.eq(results,
              coll.find({a: {$gte: {}}}, {_id: 1}).sort({_id: 1}).hint({$natural: 1}).toArray());
    assert.eq(results, coll.find({a: {$gte: {}}}, {_id: 1}).sort({_id: 1}).toArray());

    // Test that an $in with an empty object returns the expected results when the $** index is
    // hinted.
    results = coll.find({a: {$in: [3, {}]}}, {_id: 1}).sort({_id: 1}).hint({"$**": 1}).toArray();
    assert.eq(results, [{_id: 3}, {_id: 4}, {_id: 6}, {_id: 8}]);

    // Result set should be the same as when hinting a COLLSCAN and with no hint.
    assert.eq(
        results,
        coll.find({a: {$in: [3, {}]}}, {_id: 1}).sort({_id: 1}).hint({$natural: 1}).toArray());
    assert.eq(results, coll.find({a: {$in: [3, {}]}}, {_id: 1}).sort({_id: 1}).toArray());

    // Test that a wildcard index can support equality to an empty object on a dotted field.
    results = coll.find({"a.b": {$eq: {}}}, {_id: 1}).sort({_id: 1}).hint({"$**": 1}).toArray();
    assert.eq(results, [{_id: 9}, {_id: 10}]);

    // Result set should be the same as when hinting a COLLSCAN and with no hint.
    assert.eq(results,
              coll.find({"a.b": {$eq: {}}}, {_id: 1}).sort({_id: 1}).hint({$natural: 1}).toArray());
    assert.eq(results, coll.find({"a.b": {$eq: {}}}, {_id: 1}).sort({_id: 1}).toArray());
}());