summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_sort.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/document_source_sort.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_sort.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/mongo/db/pipeline/document_source_sort.cpp b/src/mongo/db/pipeline/document_source_sort.cpp
index dcf40ba110b..02290179439 100644
--- a/src/mongo/db/pipeline/document_source_sort.cpp
+++ b/src/mongo/db/pipeline/document_source_sort.cpp
@@ -169,6 +169,23 @@ Pipeline::SourceContainer::iterator DocumentSourceSort::doOptimizeAt(
_sortExecutor->setLimit(*limit);
}
+ if (std::next(itr) == container->end()) {
+ return container->end();
+ }
+
+ if (auto nextSort = dynamic_cast<DocumentSourceSort*>((*std::next(itr)).get())) {
+ // If subsequent $sort stage exists, optimize by erasing the initial one.
+ // Since $sort is not guaranteed to be stable, we can blindly remove the first $sort.
+ auto thisLim = _sortExecutor->getLimit();
+ auto otherLim = nextSort->_sortExecutor->getLimit();
+ // When coalescing subsequent $sort stages, retain the existing/lower limit.
+ if (thisLim && (!otherLim || otherLim > thisLim)) {
+ nextSort->_sortExecutor->setLimit(thisLim);
+ }
+ Pipeline::SourceContainer::iterator ret = std::next(itr);
+ container->erase(itr);
+ return ret;
+ }
return std::next(itr);
}