summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_unwind.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/document_source_unwind.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_unwind.cpp26
1 files changed, 14 insertions, 12 deletions
diff --git a/src/mongo/db/pipeline/document_source_unwind.cpp b/src/mongo/db/pipeline/document_source_unwind.cpp
index f664c0e62ff..daf7adcd5ed 100644
--- a/src/mongo/db/pipeline/document_source_unwind.cpp
+++ b/src/mongo/db/pipeline/document_source_unwind.cpp
@@ -220,7 +220,7 @@ DocumentSource::GetNextResult DocumentSourceUnwind::doGetNext() {
}
DocumentSource::GetModPathsReturn DocumentSourceUnwind::getModifiedPaths() const {
- OrderedPathSet modifiedFields{_unwindPath.fullPath()};
+ std::set<std::string> modifiedFields{_unwindPath.fullPath()};
if (_indexPath) {
modifiedFields.insert(_indexPath->fullPath());
}
@@ -232,16 +232,19 @@ bool DocumentSourceUnwind::canPushSortBack(const DocumentSourceSort* sort) const
// otherwise when we swap the limit and unwind, we could end up providing fewer results to the
// user than expected.
if (!sort->hasLimit() || _preserveNullAndEmptyArrays) {
- auto modifiedPaths = getModifiedPaths();
+ auto unwindPath = _unwindPath.fullPath();
// Checks if any of the $sort's paths depend on the unwind path (or vice versa).
SortPattern sortKeyPattern = sort->getSortKeyPattern();
- bool sortDependsOnUnwind =
+ bool sortPathMatchesUnwindPath =
std::any_of(sortKeyPattern.begin(), sortKeyPattern.end(), [&](auto& sortKey) {
// If 'sortKey' is a $meta expression, we can do the swap.
- return sortKey.fieldPath && modifiedPaths.canModify(*sortKey.fieldPath);
+ if (!sortKey.fieldPath)
+ return false;
+ return expression::bidirectionalPathPrefixOf(unwindPath,
+ sortKey.fieldPath->fullPath());
});
- return !sortDependsOnUnwind;
+ return !sortPathMatchesUnwindPath;
}
return false;
}
@@ -290,13 +293,12 @@ Pipeline::SourceContainer::iterator DocumentSourceUnwind::doOptimizeAt(
return std::next(itr);
}
-Value DocumentSourceUnwind::serialize(const SerializationOptions& opts) const {
- return Value(DOC(
- getSourceName() << DOC(
- "path" << opts.serializeFieldPathWithPrefix(_unwindPath) << "preserveNullAndEmptyArrays"
- << (_preserveNullAndEmptyArrays ? opts.serializeLiteral(true) : Value())
- << "includeArrayIndex"
- << (_indexPath ? Value(opts.serializeFieldPath(*_indexPath)) : Value()))));
+Value DocumentSourceUnwind::serialize(boost::optional<ExplainOptions::Verbosity> explain) const {
+ return Value(DOC(getSourceName() << DOC(
+ "path" << _unwindPath.fullPathWithPrefix() << "preserveNullAndEmptyArrays"
+ << (_preserveNullAndEmptyArrays ? Value(true) : Value())
+ << "includeArrayIndex"
+ << (_indexPath ? Value((*_indexPath).fullPath()) : Value()))));
}
DepsTracker::State DocumentSourceUnwind::getDependencies(DepsTracker* deps) const {