summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Seyster <justin.seyster@mongodb.com>2019-11-02 02:15:02 +0000
committerevergreen <evergreen@mongodb.com>2019-11-02 02:15:02 +0000
commit18ae8ffc431b1dcdf72c9cf3ee07323b916bf16e (patch)
tree267bc3a9182785acb45a626bdc6da75954858529 /src
parent293fe1ce7153e62ffcd59dee0dabf1f28c2ccbe1 (diff)
downloadmongo-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.cpp8
-rw-r--r--src/mongo/db/exec/document_value/document.h9
-rw-r--r--src/mongo/db/index/sort_key_generator.cpp12
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);
}