diff options
author | Justin Seyster <justin.seyster@mongodb.com> | 2019-11-02 02:15:02 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-11-02 02:15:02 +0000 |
commit | 18ae8ffc431b1dcdf72c9cf3ee07323b916bf16e (patch) | |
tree | 267bc3a9182785acb45a626bdc6da75954858529 /src | |
parent | 293fe1ce7153e62ffcd59dee0dabf1f28c2ccbe1 (diff) | |
download | mongo-18ae8ffc431b1dcdf72c9cf3ee07323b916bf16e.tar.gz |
SERVER-44383 Use trivial BSON conversion for sort key generation
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/exec/document_value/document.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/exec/document_value/document.h | 9 | ||||
-rw-r--r-- | src/mongo/db/index/sort_key_generator.cpp | 12 |
3 files changed, 26 insertions, 3 deletions
diff --git a/src/mongo/db/exec/document_value/document.cpp b/src/mongo/db/exec/document_value/document.cpp index c50648c0e20..dac2e0dde60 100644 --- a/src/mongo/db/exec/document_value/document.cpp +++ b/src/mongo/db/exec/document_value/document.cpp @@ -461,6 +461,14 @@ BSONObj Document::toBson() const { return bb.obj(); } +boost::optional<BSONObj> Document::toBsonIfTriviallyConvertible() const { + if (!storage().isModified() && !storage().stripMetadata()) { + return storage().bsonObj(); + } else { + return boost::none; + } +} + constexpr StringData Document::metaFieldTextScore; constexpr StringData Document::metaFieldRandVal; constexpr StringData Document::metaFieldSortKey; diff --git a/src/mongo/db/exec/document_value/document.h b/src/mongo/db/exec/document_value/document.h index 73a72175db6..2c389fd2056 100644 --- a/src/mongo/db/exec/document_value/document.h +++ b/src/mongo/db/exec/document_value/document.h @@ -230,6 +230,15 @@ public: BSONObj toBson() const; /** + * Serializes this document iff the conversion is "trivial," meaning that the underlying storage + * is already in BSON format and there are no damages. No conversion is necessary; this function + * just returns the already existing BSON. + * + * When the trivial conversion is not possible, this function returns boost::none. + */ + boost::optional<BSONObj> toBsonIfTriviallyConvertible() const; + + /** * Like the 'toBson()' method, but includes metadata at the top-level. When * 'use42ChangeStreamSortKeys' is true, we assume that any Value in the "sortKey" metadata * represents the resume token, which gets assigned directly to the "$sortKey" field. Otherwise, diff --git a/src/mongo/db/index/sort_key_generator.cpp b/src/mongo/db/index/sort_key_generator.cpp index a09622bb316..2719682a77b 100644 --- a/src/mongo/db/index/sort_key_generator.cpp +++ b/src/mongo/db/index/sort_key_generator.cpp @@ -260,9 +260,15 @@ StatusWith<Value> SortKeyGenerator::extractKeyFast(const Document& doc, BSONObj SortKeyGenerator::extractKeyWithArray(const Document& doc, const DocumentMetadataFields& metadata) const { - // Convert the Document to a BSONObj, but only do the conversion for the paths we actually need. - // Then run the result through the SortKeyGenerator to obtain the final sort key. - auto bsonDoc = _sortPattern.documentToBsonWithSortPaths(doc); + // Sort key generation requires the Document to be in BSON format. First, we attempt the + // "trivial" conversion, which returns the Document's BSON storage. + auto optionalBsonDoc = doc.toBsonIfTriviallyConvertible(); + + // If the trivial conversion is not possible, we perform a conversion that only converts the + // paths we need to generate the sort key. + auto bsonDoc = optionalBsonDoc ? std::move(*optionalBsonDoc) + : _sortPattern.documentToBsonWithSortPaths(doc); + return computeSortKeyFromDocument(bsonDoc, metadata); } |