summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/logs_query_hash.js
blob: b7b6205b2f1f1f8ac432252138c5da4d4fd1cc6d (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
/**
 * Tests that the queryHash and planCacheKey are logged correctly.
 */
(function() {
"use strict";

const conn = MongoRunner.runMongod();
assert.neq(null, conn, "mongod was unable to start up");
const db = conn.getDB("jstests_logs_query_hash");

// Set logLevel to 1 so that all queries will be logged.
assert.commandWorked(db.setLogLevel(1));

// Set up collections foo and bar.
db.foo.drop();
assert.commandWorked(db.foo.insert({a: 1, b: 1, c: 1}));
assert.commandWorked(db.foo.createIndexes([{a: 1, b: 1}, {b: 1, a: 1}]));

db.bar.drop();
assert.commandWorked(db.bar.insert({a: 1, b: 1, c: 1}));
assert.commandWorked(db.bar.createIndexes([{a: 1, b: 1, c: 1}, {b: 1, a: 1, c: 1}]));

// Ensure the slow query log contains the same queryHash and planCacheKey as the explain output.
function runAndVerifySlowQueryLog(pipeline, commentObj, hint) {
    assert.eq(db.foo.aggregate(pipeline, commentObj, hint).itcount(), 1);
    let queryPlanner =
        db.foo.explain().aggregate(pipeline, commentObj, hint).stages[0].$cursor.queryPlanner;
    const logId = 51803;
    let expectedLog = {};
    expectedLog.command = {};
    expectedLog.command.cursor = {};
    expectedLog.command.comment = commentObj.comment;
    expectedLog.queryHash = queryPlanner.queryHash;
    expectedLog.planCacheKey = queryPlanner.planCacheKey;
    assert(checkLog.checkContainsWithCountJson(db, logId, expectedLog, 2, null, true),
           "failed to find [" + tojson(expectedLog) + "] in the slow query log");
}

const lookupStage = {
    "$lookup": {
        "from": "bar",
        "let": {"b": {"$ifNull": ["$b", null]}},
        "pipeline": [
            {"$match": {"$or": [{"a": {"$exists": false}}, {"a": 1}]}},
            {"$match": {"$expr": {"$eq": ["$b", "$$b"]}}}
        ],
        "as": "bar"
    }
};

runAndVerifySlowQueryLog([{"$match": {$or: [{a: 1}, {b: 1}]}}, lookupStage],
                         {"comment": "pipeline1"});
runAndVerifySlowQueryLog([{"$match": {a: {$in: [1, 2, 3, 4, 5]}}}, lookupStage],
                         {"comment": "pipeline2"});
runAndVerifySlowQueryLog([{"$match": {b: 1}}, lookupStage], {"comment": "pipeline3"});

const hint = {
    "hint": {"a": 1, "b": 1}
};

runAndVerifySlowQueryLog(
    [{"$match": {$or: [{a: 1}, {b: 1}]}}, lookupStage], {"comment": "pipelineWithHint1"}, hint);
runAndVerifySlowQueryLog(
    [{"$match": {a: {$in: [1, 2, 3, 4, 5]}}}, lookupStage], {"comment": "pipelineWithHint2"}, hint);
runAndVerifySlowQueryLog([{"$match": {b: 1}}, lookupStage], {"comment": "pipelineWithHint3"}, hint);

MongoRunner.stopMongod(conn);
})();