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

Manually build ES pagination query for default sorter #4271

Merged
merged 1 commit into from
May 11, 2023

Conversation

rodrigozhou
Copy link
Contributor

What changed?
Manually build pagination query in ES when using default sorter.

Why?
In cases of deep pagination, manually building the pagination query works faster than using search_after.

How did you test it?
Existing tests.

Potential risks
No.

Is hotfix candidate?
No.

@rodrigozhou rodrigozhou requested review from alexshtin and yiminc May 3, 2023 16:55
@rodrigozhou rodrigozhou requested a review from a team as a code owner May 3, 2023 16:55
Comment on lines 671 to 676
for k := 0; k < len(defaultSorterFields); k++ {
bq := elastic.NewBoolQuery()
for i := 0; i <= k; i++ {
tp, err := saTypeMap.GetType(defaultSorterFields[i].name)
if err != nil {
return err
}

isNull := false
switch tp {
case enumspb.INDEXED_VALUE_TYPE_INT,
enumspb.INDEXED_VALUE_TYPE_BOOL,
enumspb.INDEXED_VALUE_TYPE_DATETIME:
isNull = searchAfter[i] == math.MaxInt64 || searchAfter[i] == math.MinInt64
case enumspb.INDEXED_VALUE_TYPE_DOUBLE:
isNull = searchAfter[i] == "Infinity" || searchAfter[i] == "-Infinity"
case enumspb.INDEXED_VALUE_TYPE_KEYWORD:
isNull = searchAfter[i] == nil
default:
return serviceerror.NewInternal(fmt.Sprintf(
"Invalid field type in default sorter: cannot order by %q",
defaultSorterFields[i].name,
))
}

if i == len(defaultSorterFields)-1 && isNull {
return serviceerror.NewInternal(fmt.Sprintf(
"Last field of default sorter cannot be a nullable field: %q has null values",
defaultSorterFields[i].name,
))
}

lastValue := searchAfter[i]
if tp == enumspb.INDEXED_VALUE_TYPE_DATETIME && !isNull {
ts, ok := searchAfter[i].(int64)
if !ok {
return fmt.Errorf("Invalid page token: expected unix timestamp, got %v", searchAfter[i])
}
lastValue = time.Unix(0, ts).Format(time.RFC3339Nano)
}

if isNull {
bq.MustNot(elastic.NewExistsQuery(defaultSorterFields[i].name))
} else if i < k {
bq.Filter(elastic.NewTermQuery(defaultSorterFields[i].name, lastValue))
} else if defaultSorterFields[i].desc {
bq.Filter(elastic.NewRangeQuery(defaultSorterFields[i].name).Lt(lastValue))
} else {
bq.Filter(elastic.NewRangeQuery(defaultSorterFields[i].name).Gt(lastValue))
}
}
shouldQueries = append(shouldQueries, bq)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote a generic page token query just in case the default sorter is changed.

@rodrigozhou rodrigozhou force-pushed the optimize-pagination-es branch 5 times, most recently from ebb5dbf to d004216 Compare May 5, 2023 00:42
@rodrigozhou rodrigozhou force-pushed the optimize-pagination-es branch from d004216 to 056ab3d Compare May 11, 2023 01:03
@rodrigozhou rodrigozhou force-pushed the optimize-pagination-es branch from 056ab3d to 624149b Compare May 11, 2023 17:51
@rodrigozhou rodrigozhou merged commit a1fe0e6 into temporalio:master May 11, 2023
@rodrigozhou rodrigozhou deleted the optimize-pagination-es branch May 11, 2023 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants