Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pushdown simplest sorting for aggregate command #2530

Merged
merged 26 commits into from
May 3, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
wip
  • Loading branch information
rumyantseva committed May 2, 2023
commit ccfbe614e5fb09e8716379b318908625e22861e7
36 changes: 20 additions & 16 deletions internal/handlers/common/aggregations/stages/pushdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,26 @@ import (
"github.com/FerretDB/FerretDB/internal/util/must"
)

// GetPushdownQuery gets pushdown query for aggregation.
// When the first two aggregation stages are $match or $sort they are
// used for pushdown, and returned in order: $match, $sort, otherwise nil is return.
// If any of those stages repeat in first two stages, it also returns nil.
func GetPushdownQuery(stagesDocs []any) (*types.Document, *types.Document) {
// GetPushdownQuery gets pushdown query ($match and $sort) for aggregation.
//
// If the first two stages are either $match, $sort, or a combination of them, we can push them down.
// In this case, we return the first match and sort statements to pushdown.
// If $match stage is not present, match is returned as nil.
// If $sort stage is not present, sort is returned as nil.
func GetPushdownQuery(stagesDocs []any) (match *types.Document, sort *types.Document) {
if len(stagesDocs) == 0 {
return nil, nil
return
}

var match, sort *types.Document
stagesToPushdown := []any{stagesDocs[0]}

for i, doc := range stagesDocs {
if i > 2 {
break
}
if len(stagesDocs) > 1 {
stagesToPushdown = append(stagesToPushdown, stagesDocs[1])
}

for _, s := range stagesToPushdown {
stage, isDoc := s.(*types.Document)

stage, isDoc := doc.(*types.Document)
if !isDoc {
return nil, nil
}
Expand All @@ -46,7 +49,7 @@ func GetPushdownQuery(stagesDocs []any) (*types.Document, *types.Document) {
query, isDoc := matchQuery.(*types.Document)

if !isDoc || match != nil {
return nil, nil
continue
}

match = query
Expand All @@ -56,15 +59,16 @@ func GetPushdownQuery(stagesDocs []any) (*types.Document, *types.Document) {
query, isDoc := sortQuery.(*types.Document)

if !isDoc || sort != nil {
return nil, nil
continue
}

sort = query

default:
return nil, nil
// not $match nor $sort, we shouldn't continue pushdown
return
}
}

return match, sort
return
}