summaryrefslogtreecommitdiff
path: root/jstests/aggregation/expressions/in.js
blob: ba09b0f8fac699a4309994de6a6602d7878e1d66 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// SERVER-6146 introduced the $in expression to aggregation. In this file, we test the functionality
// and error cases of the expression.
load("jstests/aggregation/extras/utils.js");  // For assertErrorCode.

(function() {
    "use strict";

    var coll = db.in ;
    coll.drop();

    function testExpression(options) {
        var pipeline = {$project: {included: {$in: ["$elementField", {$literal: options.array}]}}};

        coll.drop();
        assert.writeOK(coll.insert({elementField: options.element}));
        var res = coll.aggregate(pipeline).toArray();
        assert.eq(res.length, 1);
        assert.eq(res[0].included, options.elementIsIncluded);

        if (options.queryFormShouldBeEquivalent) {
            var query = {elementField: {$in: options.array}};
            res = coll.find(query).toArray();

            if (options.elementIsIncluded) {
                assert.eq(res.length, 1);
            } else {
                assert.eq(res.length, 0);
            }
        }
    }

    testExpression(
        {element: 1, array: [1, 2, 3], elementIsIncluded: true, queryFormShouldBeEquivalent: true});

    testExpression({
        element: "A",
        array: ["a", "A", "a"],
        elementIsIncluded: true,
        queryFormShouldBeEquivalent: true
    });

    testExpression({
        element: {a: 1},
        array: [{b: 1}, 2],
        elementIsIncluded: false,
        queryFormShouldBeEquivalent: true
    });

    testExpression({
        element: {a: 1},
        array: [{a: 1}],
        elementIsIncluded: true,
        queryFormShouldBeEquivalent: true
    });

    testExpression({
        element: [1, 2],
        array: [[2, 1]],
        elementIsIncluded: false,
        queryFormShouldBeEquivalent: true
    });

    testExpression({
        element: [1, 2],
        array: [[1, 2]],
        elementIsIncluded: true,
        queryFormShouldBeEquivalent: true
    });

    testExpression(
        {element: 1, array: [], elementIsIncluded: false, queryFormShouldBeEquivalent: true});

    // Aggregation's $in has parity with query's $in except with regexes matching string values and
    // equality semantics with array values.

    testExpression({
        element: "abc",
        array: [/a/, /b/, /c/],
        elementIsIncluded: false,
        queryFormShouldBeEquivalent: false
    });

    testExpression({
        element: /a/,
        array: ["a", "b", "c"],
        elementIsIncluded: false,
        queryFormShouldBeEquivalent: false
    });

    testExpression({
        element: [],
        array: [1, 2, 3],
        elementIsIncluded: false,
        queryFormShouldBeEquivalent: false
    });

    testExpression({
        element: [1],
        array: [1, 2, 3],
        elementIsIncluded: false,
        queryFormShouldBeEquivalent: false
    });

    testExpression({
        element: [1, 2],
        array: [1, 2, 3],
        elementIsIncluded: false,
        queryFormShouldBeEquivalent: false
    });

    coll.drop();
    coll.insert({});

    var pipeline = {$project: {included: {$in: [[1, 2], 1]}}};
    assertErrorCode(coll, pipeline, 40081, "$in requires an array as a second argument");

    pipeline = {$project: {included: {$in: [1, null]}}};
    assertErrorCode(coll, pipeline, 40081, "$in requires an array as a second argument");

    pipeline = {$project: {included: {$in: [1, "$notAField"]}}};
    assertErrorCode(coll, pipeline, 40081, "$in requires an array as a second argument");

    pipeline = {$project: {included: {$in: null}}};
    assertErrorCode(coll, pipeline, 16020, "$in requires two arguments");

    pipeline = {$project: {included: {$in: [1]}}};
    assertErrorCode(coll, pipeline, 16020, "$in requires two arguments");

    pipeline = {$project: {included: {$in: []}}};
    assertErrorCode(coll, pipeline, 16020, "$in requires two arguments");

    pipeline = {$project: {included: {$in: [1, 2, 3]}}};
    assertErrorCode(coll, pipeline, 16020, "$in requires two arguments");
}());