Skip to content

Commit

Permalink
support sending aggregations
Browse files Browse the repository at this point in the history
  • Loading branch information
trinity-1686a committed May 11, 2024
1 parent b31343f commit 8f6e7e0
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export function MetricKind(props: SearchComponentProps) {
sx={{ "min-height": "44px" }}
>
<MenuItem value="count">Count</MenuItem>
<MenuItem value="average">Average</MenuItem>
<MenuItem value="avg">Average</MenuItem>
<MenuItem value="sum">Sum</MenuItem>
<MenuItem value="max">Max</MenuItem>
<MenuItem value="min">Min</MenuItem>
Expand Down
2 changes: 1 addition & 1 deletion quickwit/quickwit-ui/src/services/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ describe('Client unit test', () => {
histogram: null,
},
};
expect(new Client().buildSearchUrl(searchRequest).toString()).toBe("http://localhost/api/v1/my-new-fresh-index-id/search?query=severity_error%3AERROR&max_hits=20&start_timestamp=100&end_timestamp=200&sort_by_field=%2Btimestamp");
expect(new Client().buildSearchBody(searchRequest, null)).toBe('{"query":"severity_error:ERROR","max_hits":20,"start_timestamp":100,"end_timestamp":200,"sort_by_field":"+timestamp"}');
});
});
118 changes: 95 additions & 23 deletions quickwit/quickwit-ui/src/services/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ export class Client {
return this._host + "/api/v1/";
}

async search(request: SearchRequest): Promise<SearchResponse> {
async search(request: SearchRequest, timestamp_field: string | null): Promise<SearchResponse> {
// TODO: improve validation of request.
if (request.indexId === null || request.indexId === undefined) {
throw Error("Search request must have and index id.")
}
const url = this.buildSearchUrl(request);
return this.fetch(url.toString(), this.defaultGetRequestParams());
const url = `${this.apiRoot()}/${request.indexId}/search`;
const body = this.buildSearchBody(request, timestamp_field);
return this.fetch(url, this.defaultGetRequestParams(), body);
}

async cluster(): Promise<Cluster> {
Expand Down Expand Up @@ -85,7 +86,12 @@ export class Client {
return this.fetch(`${this.apiRoot()}indexes`, {});
}

async fetch<T>(url: string, params: RequestInit): Promise<T> {
async fetch<T>(url: string, params: RequestInit, body: string|null = null): Promise<T> {
if (body !== null) {
params.method = "POST";
params.body = body;
params.headers = Object.assign({}, params.headers, {"content-type": "application/json"});
}
const response = await fetch(url, params);
if (response.ok) {
return response.json() as Promise<T>;
Expand All @@ -101,34 +107,100 @@ export class Client {
return {
method: "GET",
headers: { Accept: "application/json" },
mode: "no-cors",
mode: "cors",
cache: "default",
}
}

buildSearchUrl(request: SearchRequest): URL {
const url: URL = new URL(`${request.indexId}/search`, this.apiRoot());
// TODO: the trim should be done in the backend.
url.searchParams.append("query", request.query.trim() || "*");
url.searchParams.append("max_hits", "20");
buildSearchBody(request: SearchRequest, timestamp_field: string | null): string {
/* eslint-disable @typescript-eslint/no-explicit-any */
const body: any = {
// TODO: the trim should be done in the backend.
query: request.query.trim() || "*",
};

if (request.aggregation) {
const qw_aggregation = this.buildAggregation(request, timestamp_field);
body["aggs"] = qw_aggregation;
body["max_hits"] = 0;
} else {
body["max_hits"] = 20;
}
if (request.startTimestamp) {
url.searchParams.append(
"start_timestamp",
request.startTimestamp.toString()
);
body["start_timestamp"] = request.startTimestamp;
}
if (request.endTimestamp) {
url.searchParams.append(
"end_timestamp",
request.endTimestamp.toString()
);
body["end_timestamp"] = request.endTimestamp;
}
if (request.sortByField) {
url.searchParams.append(
"sort_by_field",
serializeSortByField(request.sortByField)
);
body["sort_by_field"] = serializeSortByField(request.sortByField);
}
return JSON.stringify(body);
}

/* eslint-disable @typescript-eslint/no-explicit-any */
buildAggregation(request: SearchRequest, timestamp_field: string | null): any {
let aggregation = undefined;
if (request.aggregationConfig.metric) {
const metric = request.aggregationConfig.metric;
aggregation = {
metric: {
[metric.type]: {
field: metric.field
}
}
}
}
if (request.aggregationConfig.histogram && timestamp_field) {
const histogram = request.aggregationConfig.histogram;
let auto;
if (request.endTimestamp == null || request.startTimestamp == null) {
auto = "1d";
} else if ((request.endTimestamp - request.startTimestamp) > 7 * 24 * 60 * 60) {
auto = "1d";
} else if ((request.endTimestamp - request.startTimestamp) > 24 * 60 * 60) {
auto = "10m"
} else {
auto = "1m"
}
const interval = histogram.interval !== "auto" ? histogram.interval : auto;
let extended_bounds;
if (request.startTimestamp && request.endTimestamp) {
extended_bounds = {
min: request.startTimestamp,
max: request.endTimestamp,
};
} else {
extended_bounds = undefined;
}
aggregation = {
histo_agg: {
aggs: aggregation,
date_histogram: {
field: timestamp_field,
fixed_interval: interval,
min_doc_count: 0,
extended_bounds: extended_bounds,
}
}
}
}
if (request.aggregationConfig.term) {
const term = request.aggregationConfig.term;
aggregation = {
term_agg: {
aggs: aggregation,
terms: {
field: term.field,
size: term.size,
order: {
_count: "desc"
},
min_doc_count: 1,
}
}
}
}
return url;
return aggregation;
}
}
1 change: 1 addition & 0 deletions quickwit/quickwit-ui/src/utils/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export type SearchResponse = {
hits: Array<RawDoc>;
elapsed_time_micros: number;
errors: Array<any> | undefined;
aggregations: any | undefined;
}

export type IndexConfig = {
Expand Down
3 changes: 2 additions & 1 deletion quickwit/quickwit-ui/src/views/SearchView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ function SearchView() {
setQueryRunning(true);
setSearchError(null);
navigate('/search?' + toUrlSearchRequestParams(updatedSearchRequest).toString());
quickwitClient.search(updatedSearchRequest).then((response) => {
const timestamp_field = index?.metadata.index_config.doc_mapping.timestamp_field || null;
quickwitClient.search(updatedSearchRequest, timestamp_field).then((response) => {
updateLastSearchRequest(updatedSearchRequest);
setSearchResponse(response);
setQueryRunning(false);
Expand Down

0 comments on commit 8f6e7e0

Please sign in to comment.