From 2f667bface2924113e5812be0972874bb95e6436 Mon Sep 17 00:00:00 2001 From: Maddie Zechar Date: Thu, 11 May 2023 14:41:01 +0000 Subject: SERVER-76143 Add missing find command fields to queryStats key --- jstests/libs/telemetry_utils.js | 7 +- .../telemetry/application_name_find.js | 44 ++------ jstests/noPassthrough/telemetry/query_stats_key.js | 111 +++++++++++++++++++++ .../telemetry/telemetry_collect_on_mongos.js | 8 +- .../telemetry_metrics_across_getMore_calls.js | 2 +- .../telemetry/telemetry_redact_find_cmd.js | 4 +- src/mongo/db/query/find_request_shapifier.cpp | 44 +++++++- src/mongo/db/query/query_shape.cpp | 35 +------ src/mongo/db/query/telemetry.cpp | 2 - src/mongo/db/query/telemetry_store_test.cpp | 101 +++++++++++++++---- 10 files changed, 252 insertions(+), 106 deletions(-) create mode 100644 jstests/noPassthrough/telemetry/query_stats_key.js diff --git a/jstests/libs/telemetry_utils.js b/jstests/libs/telemetry_utils.js index 5b7b1d32e5b..11e2d236827 100644 --- a/jstests/libs/telemetry_utils.js +++ b/jstests/libs/telemetry_utils.js @@ -61,14 +61,11 @@ function getTelemetryRedacted( applyHmacToIdentifiers = true, hmacKey = BinData(0, "MjM0NTY3ODkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjE=")) { // Hashed application name is generated using the default hmacKey argument. - const kApplicationName = "T1iwlAqhXYroi7HTycmBJvWZSETwKXnaNa5akM4q0H4="; + const kApplicationName = "MongoDB Shell"; // Filter out agg queries, including $telemetry. const match = { - $match: {"key.queryShape.find": {$exists: true}, "key.applicationName": kApplicationName} + $match: {"key.queryShape.command": "find", "key.applicationName": kApplicationName} }; - if (!applyHmacToIdentifiers) { - match.$match["key.applicationName"] = "MongoDB Shell"; - } const result = conn.adminCommand({ aggregate: 1, diff --git a/jstests/noPassthrough/telemetry/application_name_find.js b/jstests/noPassthrough/telemetry/application_name_find.js index 11a073522f0..35b86a95f53 100644 --- a/jstests/noPassthrough/telemetry/application_name_find.js +++ b/jstests/noPassthrough/telemetry/application_name_find.js @@ -2,26 +2,13 @@ * Test that applicationName and namespace appear in telemetry for the find command. * @tags: [featureFlagTelemetry] */ +load("jstests/libs/telemetry_utils.js"); (function() { "use strict"; const kApplicationName = "MongoDB Shell"; -const kHashedApplicationName = "piOJ84Zjy9dJP6snMI5X6NQ42VGim3vofK5awkuY5q8="; - -const getTelemetry = (conn, applyHmacToIdentifiers = false) => { - const result = assert.commandWorked(conn.adminCommand({ - aggregate: 1, - pipeline: [ - {$telemetry: {applyHmacToIdentifiers}}, - // Sort on telemetry key so entries are in a deterministic order. - {$sort: {key: 1}}, - {$match: {"key.applicationName": {$in: [kApplicationName, kHashedApplicationName]}}}, - {$match: {"key.queryShape.find": {$exists: true}}} - ], - cursor: {batchSize: 10} - })); - return result.cursor.firstBatch; -}; +const kHashedCollName = "w6Ax20mVkbJu4wQWAMjL8Sl+DfXAr2Zqdc3kJRB7Oo0="; +const kHashedFieldName = "lU7Z0mLRPRUL+RfAD5jhYPRRpXBsZBxS/20EzDwfOG4="; // Turn on the collecting of telemetry metrics. let options = { @@ -42,30 +29,11 @@ coll.find({v: 1}).toArray(); let telemetry = getTelemetry(conn); assert.eq(1, telemetry.length, telemetry); -assert.eq({ - queryShape: { - cmdNs: {db: testDB.getName(), coll: coll.getName()}, - find: coll.getName(), - filter: {v: {"$eq": "?number"}}, - }, - applicationName: kApplicationName -}, - telemetry[0].key, - telemetry); +assert.eq(kApplicationName, telemetry[0].key.applicationName, telemetry); -telemetry = getTelemetry(conn, true); +telemetry = getTelemetryRedacted(conn, true); assert.eq(1, telemetry.length, telemetry); -const hashedColl = "tU+RtrEU9QHrWsxNIL8OUDvfpUdavYkcuw7evPKfxdU="; -assert.eq({ - queryShape: { - cmdNs: {db: "Q7DO+ZJl+eNMEOqdNQGSbSezn1fG1nRWHYuiNueoGfs=", coll: hashedColl}, - find: hashedColl, - filter: {"ksdi13D4gc1BJ0Es4yX6QtG6MAwIeNLsCgeGRePOvFE=": {"$eq": "?number"}}, - }, - applicationName: kHashedApplicationName -}, - telemetry[0].key, - telemetry); +assert.eq(kApplicationName, telemetry[0].key.applicationName, telemetry); MongoRunner.stopMongod(conn); }()); diff --git a/jstests/noPassthrough/telemetry/query_stats_key.js b/jstests/noPassthrough/telemetry/query_stats_key.js new file mode 100644 index 00000000000..68d77110bc6 --- /dev/null +++ b/jstests/noPassthrough/telemetry/query_stats_key.js @@ -0,0 +1,111 @@ +/** + * This test confirms that telemetry store key fields are properly nested and none are missing. + * @tags: [featureFlagTelemetry] + */ +load("jstests/libs/telemetry_utils.js"); +(function() { +"use strict"; + +function confirmAllFieldsPresent(queryStatsEntries) { + const kApplicationName = "MongoDB Shell"; + const queryShapeFindFields = [ + "cmdNs", + "command", + "filter", + "sort", + "projection", + "hint", + "skip", + "limit", + "singleBatch", + "max", + "min", + "returnKey", + "showRecordId", + "tailable", + "oplogReplay", + "awaitData", + "collation", + "allowDiskUse", + "let" + ]; + + // The outer fields not nested inside queryShape. + const queryStatsKeyFields = [ + "queryShape", + "batchSize", + "comment", + "maxTimeMS", + "noCursorTimeout", + "readConcern", + "allowPartialResults", + "applicationName" + ]; + + for (const entry of queryStatsEntries) { + let fieldCounter = 0; + assert.eq(entry.key.queryShape.command, "find"); + assert.eq(entry.key.applicationName, kApplicationName); + + for (const field in entry.key.queryShape) { + assert(queryShapeFindFields.includes(field)); + fieldCounter++; + } + assert.eq(fieldCounter, queryShapeFindFields.length); + + fieldCounter = 0; + for (const field in entry.key) { + assert(queryStatsKeyFields.includes(field)); + fieldCounter++; + } + assert.eq(fieldCounter, queryStatsKeyFields.length); + } +} + +// Turn on the collecting of telemetry metrics. +let options = { + setParameter: {internalQueryConfigureTelemetrySamplingRate: -1}, +}; + +const conn = MongoRunner.runMongod(options); +const testDB = conn.getDB('test'); +var coll = testDB[jsTestName()]; +coll.drop(); + +// Have to create an index for hint not to fail. +assert.commandWorked(coll.createIndex({v: 1})); + +let commandObj = { + find: coll.getName(), + filter: {v: {$eq: 2}}, + oplogReplay: true, + comment: "this is a test!!", + min: {"v": 0}, + max: {"v": 4}, + hint: {"v": 1}, + sort: {a: -1}, + returnKey: false, + noCursorTimeout: true, + showRecordId: false, + tailable: false, + awaitData: false, + allowPartialResults: true, + skip: 1, + limit: 2, + maxTimeMS: 500, + collation: {locale: "en_US", strength: 2}, + allowDiskUse: true, + readConcern: {level: "local"}, + batchSize: 2, + singleBatch: true, + let : {}, + projection: {_id: 0}, +}; + +assert.commandWorked(testDB.runCommand(commandObj)); +let telemetry = getTelemetry(conn); +assert.eq(1, telemetry.length); +confirmAllFieldsPresent(telemetry); + +MongoRunner.stopMongod(conn); +}()); diff --git a/jstests/noPassthrough/telemetry/telemetry_collect_on_mongos.js b/jstests/noPassthrough/telemetry/telemetry_collect_on_mongos.js index 69a6b79ba18..97e4f9df3cf 100644 --- a/jstests/noPassthrough/telemetry/telemetry_collect_on_mongos.js +++ b/jstests/noPassthrough/telemetry/telemetry_collect_on_mongos.js @@ -73,11 +73,11 @@ const assertExpectedResults = (results, const telemetryKey = { queryShape: { cmdNs: {db: "test", coll: "coll"}, - find: collName, + command: "find", filter: {$and: [{v: {$gt: "?number"}}, {v: {$lt: "?number"}}]}, - batchSize: "?number", }, readConcern: {level: "local", provenance: "implicitDefault"}, + batchSize: "?number", applicationName: "MongoDB Shell", }; @@ -208,11 +208,11 @@ const assertExpectedResults = (results, const telemetryKey = { queryShape: { cmdNs: {db: "test", coll: "coll"}, - find: collName, + command: "find", filter: {$and: [{v: {$gt: "?number"}}, {v: {$lt: "?number"}}]}, - batchSize: "?number", }, readConcern: {level: "local", provenance: "implicitDefault"}, + batchSize: "?number", applicationName: "MongoDB Shell" }; diff --git a/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js b/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js index 657f036b551..91605c5e069 100644 --- a/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js +++ b/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js @@ -102,7 +102,7 @@ const fooNeBatchSize = 3; // This filters telemetry entires to just the ones entered when running above find queries. let telemetryResults = testDB.getSiblingDB("admin") - .aggregate([{$telemetry: {}}, {$match: {"key.queryShape.find": {$exists: true}}}]) + .aggregate([{$telemetry: {}}, {$match: {"key.queryShape.command": "find"}}]) .toArray(); assert.eq(telemetryResults.length, 4, telemetryResults); diff --git a/jstests/noPassthrough/telemetry/telemetry_redact_find_cmd.js b/jstests/noPassthrough/telemetry/telemetry_redact_find_cmd.js index d50e210d958..54b909adae9 100644 --- a/jstests/noPassthrough/telemetry/telemetry_redact_find_cmd.js +++ b/jstests/noPassthrough/telemetry/telemetry_redact_find_cmd.js @@ -20,7 +20,7 @@ function runTest(conn) { let telemetry = getTelemetryRedacted(admin); assert.eq(1, telemetry.length); - assert.eq(kHashedCollName, telemetry[0].key.queryShape.find); + assert.eq("find", telemetry[0].key.queryShape.command); assert.eq({[kHashedFieldName]: {$eq: "?number"}}, telemetry[0].key.queryShape.filter); db.test.insert({v: 2}); @@ -35,7 +35,7 @@ function runTest(conn) { telemetry = getTelemetryRedacted(admin); assert.eq(2, telemetry.length); - assert.eq(kHashedCollName, telemetry[1].key.queryShape.find); + assert.eq("find", telemetry[1].key.queryShape.command); assert.eq({ "$and": [{[kHashedFieldName]: {"$gt": "?number"}}, {[kHashedFieldName]: {"$lt": "?number"}}] }, diff --git a/src/mongo/db/query/find_request_shapifier.cpp b/src/mongo/db/query/find_request_shapifier.cpp index f8794683fbd..fdb96a6ad19 100644 --- a/src/mongo/db/query/find_request_shapifier.cpp +++ b/src/mongo/db/query/find_request_shapifier.cpp @@ -35,6 +35,34 @@ #include "mongo/db/query/query_shape.h" namespace mongo::telemetry { + +void addNonShapeObjCmdLiterals(BSONObjBuilder* bob, + const FindCommandRequest& findCommand, + const SerializationOptions& opts, + const boost::intrusive_ptr& expCtx) { + + if (const auto& comment = expCtx->opCtx->getComment()) { + opts.appendLiteral(bob, "comment", *comment); + } + + if (auto noCursorTimeout = findCommand.getNoCursorTimeout()) { + // Capture whether noCursorTimeout was specified in the query, do not distinguish between + // true or false. + opts.appendLiteral( + bob, FindCommandRequest::kNoCursorTimeoutFieldName, noCursorTimeout.has_value()); + } + + if (auto maxTimeMs = findCommand.getMaxTimeMS()) { + opts.appendLiteral(bob, FindCommandRequest::kMaxTimeMSFieldName, *maxTimeMs); + } + + if (auto batchSize = findCommand.getBatchSize()) { + opts.appendLiteral( + bob, FindCommandRequest::kBatchSizeFieldName, static_cast(*batchSize)); + } +} + + BSONObj FindRequestShapifier::makeTelemetryKey(const SerializationOptions& opts, OperationContext* opCtx) const { auto expCtx = make_intrusive( @@ -57,12 +85,24 @@ BSONObj FindRequestShapifier::makeTelemetryKey( // Read concern should not be considered a literal. bob.append(FindCommandRequest::kReadConcernFieldName, optObj.get()); } + // has_value() returns true if allowParitalResults was populated by the original query. + if (_request.getAllowPartialResults().has_value()) { + // Note we are intentionally avoiding opts.appendLiteral() here and want to keep the exact + // value. value_or() will return the stored value, or the default that is passed in. Since + // we've already checked that allowPartialResults has a stored value, the default will never + // be used. + bob.append(FindCommandRequest::kAllowPartialResultsFieldName, + _request.getAllowPartialResults().value_or(false)); + } + + // Fields for literal redaction. Adds comment, batchSize, maxTimeMS, and noCursorTimeOut. + addNonShapeObjCmdLiterals(&bob, _request, opts, expCtx); if (_applicationName.has_value()) { - // TODO SERVER-76143 don't serialize appName - bob.append("applicationName", opts.serializeIdentifier(_applicationName.value())); + bob.append("applicationName", _applicationName.value()); } + return bob.obj(); } } // namespace mongo::telemetry diff --git a/src/mongo/db/query/query_shape.cpp b/src/mongo/db/query/query_shape.cpp index 817583304a0..519b1115558 100644 --- a/src/mongo/db/query/query_shape.cpp +++ b/src/mongo/db/query/query_shape.cpp @@ -100,10 +100,9 @@ BSONObj extractSortShape(const BSONObj& sortSpec, } static std::string hintSpecialField = "$hint"; -void addLiteralFields(BSONObjBuilder* bob, +void addShapeLiterals(BSONObjBuilder* bob, const FindCommandRequest& findCommand, const SerializationOptions& opts) { - if (auto limit = findCommand.getLimit()) { opts.appendLiteral( bob, FindCommandRequest::kLimitFieldName, static_cast(*limit)); @@ -111,17 +110,6 @@ void addLiteralFields(BSONObjBuilder* bob, if (auto skip = findCommand.getSkip()) { opts.appendLiteral(bob, FindCommandRequest::kSkipFieldName, static_cast(*skip)); } - if (auto batchSize = findCommand.getBatchSize()) { - opts.appendLiteral( - bob, FindCommandRequest::kBatchSizeFieldName, static_cast(*batchSize)); - } - if (auto maxTimeMs = findCommand.getMaxTimeMS()) { - opts.appendLiteral(bob, FindCommandRequest::kMaxTimeMSFieldName, *maxTimeMs); - } - if (auto noCursorTimeout = findCommand.getNoCursorTimeout()) { - opts.appendLiteral( - bob, FindCommandRequest::kNoCursorTimeoutFieldName, bool(noCursorTimeout)); - } } static std::vector< @@ -133,9 +121,8 @@ static std::vector< {FindCommandRequest::kShowRecordIdFieldName, &FindCommandRequest::getShowRecordId}, {FindCommandRequest::kTailableFieldName, &FindCommandRequest::getTailable}, {FindCommandRequest::kAwaitDataFieldName, &FindCommandRequest::getAwaitData}, - {FindCommandRequest::kAllowPartialResultsFieldName, - &FindCommandRequest::getAllowPartialResults}, {FindCommandRequest::kMirroredFieldName, &FindCommandRequest::getMirrored}, + {FindCommandRequest::kOplogReplayFieldName, &FindCommandRequest::getOplogReplay}, }; std::vector>> objArgMap = { @@ -230,19 +217,7 @@ BSONObj extractQueryShape(const FindCommandRequest& findCommand, } } - // Redact the namespace of the command. - { - auto nssOrUUID = findCommand.getNamespaceOrUUID(); - std::string toSerialize; - if (nssOrUUID.uuid()) { - toSerialize = opts.serializeIdentifier(nssOrUUID.toString()); - } else { - // Database is set at the command level, only serialize the collection here. - toSerialize = opts.serializeIdentifier(nssOrUUID.nss()->coll()); - } - bob.append(FindCommandRequest::kCommandName, toSerialize); - } - + bob.append("command", "find"); std::unique_ptr filterExpr; // Filter. { @@ -299,8 +274,8 @@ BSONObj extractQueryShape(const FindCommandRequest& findCommand, query_shape::extractSortShape(findCommand.getSort(), expCtx, opts)); } - // Fields for literal redaction. Adds limit, skip, batchSize, maxTimeMS, and noCursorTimeOut - addLiteralFields(&bob, findCommand, opts); + // Fields for literal redaction. Adds limit and skip. + addShapeLiterals(&bob, findCommand, opts); // Add the fields that require no redaction. addRemainingFindCommandFields(&bob, findCommand, opts); diff --git a/src/mongo/db/query/telemetry.cpp b/src/mongo/db/query/telemetry.cpp index 766d2a1f131..10da833147e 100644 --- a/src/mongo/db/query/telemetry.cpp +++ b/src/mongo/db/query/telemetry.cpp @@ -371,7 +371,6 @@ BSONObj TelemetryEntry::makeTelemetryKey(const BSONObj& key, [&](StringData sd) { return sha256HmacStringDataHasher(hmacKey, sd); }, LiteralSerializationPolicy::kToDebugTypeString) : SerializationOptions(false); - return requestShapifier->makeTelemetryKey(serializationOpts, opCtx); } @@ -488,7 +487,6 @@ void registerRequest(std::unique_ptr requestShapifier, if (!shouldCollect(opCtx->getServiceContext())) { return; } - SerializationOptions options; options.literalPolicy = LiteralSerializationPolicy::kToDebugTypeString; options.replacementForLiteralArgs = replacementForLiteralArgs; diff --git a/src/mongo/db/query/telemetry_store_test.cpp b/src/mongo/db/query/telemetry_store_test.cpp index e2c5fb04eca..cbf1104d29c 100644 --- a/src/mongo/db/query/telemetry_store_test.cpp +++ b/src/mongo/db/query/telemetry_store_test.cpp @@ -161,7 +161,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -182,7 +182,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -207,7 +207,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -240,7 +240,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -276,7 +276,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -318,6 +318,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { key = makeTelemetryKeyFindRequest( fcr, expCtx, true, LiteralSerializationPolicy::kToDebugTypeString); + ASSERT_BSONOBJ_EQ_AUTO( // NOLINT R"({ "queryShape": { @@ -325,7 +326,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -355,11 +356,12 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "HASH": -1 }, "limit": "?number", - "skip": "?number", - "batchSize": "?number", - "maxTimeMS": "?number" + "skip": "?number" + }, + "maxTimeMS": "?number", + "batchSize": "?number" } - })", + )", key); // Add the fields that shouldn't be hmacApplied. @@ -372,6 +374,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { fcr.setMirrored(true); key = makeTelemetryKeyFindRequest( fcr, expCtx, true, LiteralSerializationPolicy::kToDebugTypeString); + ASSERT_BSONOBJ_EQ_AUTO( // NOLINT R"({ "queryShape": { @@ -379,7 +382,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -410,15 +413,69 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestAllFields) { }, "limit": "?number", "skip": "?number", - "batchSize": "?number", - "maxTimeMS": "?number", "singleBatch": "?bool", "allowDiskUse": "?bool", "showRecordId": "?bool", "awaitData": "?bool", - "allowPartialResults": "?bool", "mirrored": "?bool" - } + }, + "allowPartialResults": true, + "maxTimeMS": "?number", + "batchSize": "?number" + })", + key); + + fcr.setAllowPartialResults(false); + key = makeTelemetryKeyFindRequest( + fcr, expCtx, true, LiteralSerializationPolicy::kToDebugTypeString); + // Make sure that a false allowPartialResults is also accurately captured. + ASSERT_BSONOBJ_EQ_AUTO( // NOLINT + R"({ + "queryShape": { + "cmdNs": { + "db": "HASH", + "coll": "HASH" + }, + "command": "find", + "filter": { + "HASH": { + "$eq": "?number" + } + }, + "let": { + "HASH": "$HASH", + "HASH": "?string" + }, + "projection": { + "HASH": true, + "HASH": true, + "HASH<_id>": true + }, + "hint": { + "HASH": 1, + "HASH": 1 + }, + "max": { + "HASH": "?" + }, + "min": { + "HASH": "?" + }, + "sort": { + "HASH": 1, + "HASH": -1 + }, + "limit": "?number", + "skip": "?number", + "singleBatch": "?bool", + "allowDiskUse": "?bool", + "showRecordId": "?bool", + "awaitData": "?bool", + "mirrored": "?bool" + }, + "allowPartialResults": false, + "maxTimeMS": "?number", + "batchSize": "?number" })", key); } @@ -443,7 +500,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsFindCommandRequestEmptyFields) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": {} } })", @@ -470,7 +527,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsHintsWithOptions) { "db": "testDB", "coll": "testColl" }, - "find": "testColl", + "command": "find", "filter": { "b": { "$eq": "?number" @@ -503,7 +560,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsHintsWithOptions) { "db": "testDB", "coll": "testColl" }, - "find": "testColl", + "command": "find", "filter": { "b": { "$eq": "?number" @@ -531,7 +588,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsHintsWithOptions) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": 1 @@ -560,7 +617,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsHintsWithOptions) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -591,7 +648,7 @@ TEST_F(TelemetryStoreTest, CorrectlyRedactsHintsWithOptions) { "db": "HASH", "coll": "HASH" }, - "find": "HASH", + "command": "find", "filter": { "HASH": { "$eq": "?number" @@ -668,7 +725,7 @@ TEST_F(TelemetryStoreTest, DefinesLetVariables) { "db": "IyuPUD33jXD1td/VA/JyhbOPYY0MdGkXgdExniXmCyg=", "coll": "QFhYnXorzWDLwH/wBgpXxp8fkfsZKo4n2cIN/O0uf/c=" }, - "find": "QFhYnXorzWDLwH/wBgpXxp8fkfsZKo4n2cIN/O0uf/c=", + "command": "find", "filter": { "$expr": [ { -- cgit v1.2.1