summaryrefslogtreecommitdiff
path: root/jstests/core/mr_multikey_deduping.js
blob: e3f729ef16f6c6297cec5b6612d88a5fdbb4acc8 (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
// Tests that the presence of an index does not impact the results of a mapReduce
// @tags: [
//   # MR commands may not see previous inserts because MR does not support causal consistency so we
//   # add this tag to exclude transactional passthroughs which commit versions in an ascynchronos
//   # fashion and can cause stale reads.
//   assumes_unsharded_collection,
//   # mapReduce does not support afterClusterTime.
//   does_not_support_causal_consistency,
//   does_not_support_stepdowns,
//   sbe_incompatible,
//   uses_map_reduce_with_temp_collections,
// ]

load("jstests/aggregation/extras/utils.js");  // For resultsEq
(function() {
"use strict";

const coll = db.mr_multikey_deduping;
coll.drop();
const outColl = db.mr_multikey_deduping_out;
outColl.drop();

(function testSingleKeyIndex() {
    assert.commandWorked(coll.insert({arr: [1, 2]}));

    const mapFn = function() {
        emit(this._id, 1);
    };
    const reduceFn = function(k, vals) {
        return Array.sum(vals);
    };

    let res = assert.commandWorked(
        coll.mapReduce(mapFn, reduceFn, {out: {merge: outColl.getName()}, query: {}}));
    assert(outColl.drop());

    res = assert.commandWorked(coll.mapReduce(
        mapFn, reduceFn, {out: {merge: outColl.getName()}, query: {arr: {$gte: 0}}}));
    assert(outColl.drop());

    // Now test that we get the same results when there's an index present.
    assert.commandWorked(coll.createIndex({arr: 1}));
    res = assert.commandWorked(coll.mapReduce(
        mapFn, reduceFn, {out: {merge: outColl.getName()}, query: {arr: {$gte: 0}}}));
    assert(outColl.drop());
}());

(function testCompoundIndex() {
    coll.drop();
    assert.commandWorked(coll.insert([
        {_id: 1, name: 'name1', tags: ['dog', 'cat']},
        {_id: 2, name: 'name2', tags: ['cat']},
        {_id: 3, name: 'name3', tags: ['mouse', 'cat', 'dog']},
        {_id: 4, name: 'name4', tags: []}
    ]));

    const mapFn = function() {
        for (var i = 0; i < this.tags.length; i++)
            emit(this.tags[i], 1);
    };

    const reduceFn = function(key, values) {
        return Array.sum(values);
    };

    const resultsNoIndexNoQuery =
        assert
            .commandWorked(db.runCommand(
                {mapreduce: coll.getName(), map: mapFn, reduce: reduceFn, out: {inline: 1}}))
            .results;
    const resultsNoIndexEqualityOnName = assert
                                             .commandWorked(db.runCommand({
                                                 mapreduce: coll.getName(),
                                                 map: mapFn,
                                                 reduce: reduceFn,
                                                 query: {name: 'name1'},
                                                 out: {inline: 1}
                                             }))
                                             .results;
    const resultsNoIndexRangeOnName = assert
                                          .commandWorked(db.runCommand({
                                              mapreduce: coll.getName(),
                                              map: mapFn,
                                              reduce: reduceFn,
                                              query: {name: {$gt: 'name'}},
                                              out: {inline: 1}
                                          }))
                                          .results;

    assert(resultsEq([{_id: "cat", value: 3}, {_id: "dog", value: 2}, {_id: "mouse", value: 1}],
                     resultsNoIndexNoQuery));
    assert(
        resultsEq([{_id: "cat", value: 1}, {_id: "dog", value: 1}], resultsNoIndexEqualityOnName));
    assert(resultsEq(resultsNoIndexNoQuery, resultsNoIndexRangeOnName));

    assert.commandWorked(coll.createIndex({name: 1, tags: 1}));

    const resultsIndexedNoQuery =
        assert
            .commandWorked(db.runCommand(
                {mapreduce: coll.getName(), map: mapFn, reduce: reduceFn, out: {inline: 1}}))
            .results;
    const resultsIndexedEqualityOnName = assert
                                             .commandWorked(db.runCommand({
                                                 mapreduce: coll.getName(),
                                                 map: mapFn,
                                                 reduce: reduceFn,
                                                 query: {name: 'name1'},
                                                 out: {inline: 1}
                                             }))
                                             .results;
    const resultsIndexedRangeOnName = assert
                                          .commandWorked(db.runCommand({
                                              mapreduce: coll.getName(),
                                              map: mapFn,
                                              reduce: reduceFn,
                                              query: {name: {$gt: 'name'}},
                                              out: {inline: 1}
                                          }))
                                          .results;

    assert(resultsEq(resultsNoIndexNoQuery, resultsIndexedNoQuery));
    assert(resultsEq(resultsNoIndexEqualityOnName, resultsIndexedEqualityOnName));
    assert(resultsEq(resultsNoIndexRangeOnName, resultsIndexedRangeOnName));
}());
}());