diff options
author | Ted Tuckman <ted.tuckman@mongodb.com> | 2021-10-21 12:52:03 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-21 13:15:57 +0000 |
commit | 4f5e64a4f2fbac9b12a24b26dddb6b772fd21e37 (patch) | |
tree | a885fdd0284c705bf449ea8bcfe4aef26b7d8d2a /src/mongo/db/pipeline/document_source_graph_lookup.cpp | |
parent | 19cf54eb17cf933dfabf5a553660d93319e51713 (diff) | |
download | mongo-4f5e64a4f2fbac9b12a24b26dddb6b772fd21e37.tar.gz |
SERVER-60755 Distinguish between null, missing, and undefined in $graphLookup
Diffstat (limited to 'src/mongo/db/pipeline/document_source_graph_lookup.cpp')
-rw-r--r-- | src/mongo/db/pipeline/document_source_graph_lookup.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup.cpp b/src/mongo/db/pipeline/document_source_graph_lookup.cpp index df0dbe22e13..60e74b9c043 100644 --- a/src/mongo/db/pipeline/document_source_graph_lookup.cpp +++ b/src/mongo/db/pipeline/document_source_graph_lookup.cpp @@ -401,6 +401,11 @@ boost::optional<BSONObj> DocumentSourceGraphLookUp::makeMatchStageFromFrontier( // // We wrap the query in a $match so that it can be parsed into a DocumentSourceMatch when // constructing a pipeline to execute. + + // $match stages will conflate null, and undefined values. Keep track of which ones are + // present and eliminate documents that would match the others later. + bool matchNull = false; + bool matchUndefined = false; BSONObjBuilder match; { BSONObjBuilder query(match.subobjStart("$match")); @@ -417,11 +422,33 @@ boost::optional<BSONObj> DocumentSourceGraphLookUp::makeMatchStageFromFrontier( { BSONArrayBuilder in(subObj.subarrayStart("$in")); for (auto&& value : _frontier) { + if (value.getType() == BSONType::jstNULL) { + matchNull = true; + } else if (value.getType() == BSONType::Undefined) { + matchUndefined = true; + } in << value; } } } } + // We never want to see documents where the 'connectToField' is missing. + auto existsMatch = BSON(_connectToField.fullPath() << BSON("$exists" << true)); + andObj << existsMatch; + // If matching null or undefined, make sure we don't match the other one. + if (matchNull || matchUndefined) { + if (!matchUndefined) { + auto notUndefined = + BSON(_connectToField.fullPath() << BSON("$not" << BSON("$type" + << "undefined"))); + andObj << notUndefined; + } else if (!matchNull) { + auto notUndefined = + BSON(_connectToField.fullPath() << BSON("$not" << BSON("$type" + << "null"))); + andObj << notUndefined; + } + } } } |