Skip to content
This repository was archived by the owner on May 12, 2026. It is now read-only.

Commit bfbeee0

Browse files
committed
fix: filters and configurable autocomplete chains
- render Quickwit-safe filters for text phrases, simple text terms, JSON arrays, numeric arrays, boolean arrays, and scalar numeric/boolean values - fix quick-filter toggle behavior so filter-in/filter-out matches by operator and replaces opposite filters instead of adding duplicates - avoid mutating query filter objects when adding or toggling quick filters - add configurable filter autocomplete limit, defaulting to 1000 and supporting 0 for no terms limit - apply autocomplete limit to tag values and field autocomplete requests - add filter chain mode datasource option: no chain, sampled chain, or full chain - dedupe tag keys when fields expose multiple capabilities - improve template multi-value interpolation for Quickwit by inferring field context and avoiding bare IN fallbacks - add focused tests for filter rendering, quick-filter toggles, autocomplete limits, chain modes, and template interpolation Signed-off-by: Patrik Cyvoct <patrik@ptrk.io>
1 parent a39e92f commit bfbeee0

9 files changed

Lines changed: 1005 additions & 177 deletions

File tree

src/QueryBuilder/elastic.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { getDataQuery } from './elastic';
2+
3+
describe('getDataQuery', () => {
4+
it('uses the requested terms size for autocomplete queries', () => {
5+
const query = getDataQuery({ field: 'status', size: 250 }, 'getTerms');
6+
7+
expect(query.bucketAggs?.[0].settings).toEqual(
8+
expect.objectContaining({
9+
size: '250',
10+
shard_size: '250',
11+
})
12+
);
13+
});
14+
15+
it('keeps zero as no terms limit', () => {
16+
const query = getDataQuery({ field: 'status', size: 0 }, 'getTerms');
17+
18+
expect(query.bucketAggs?.[0].settings).toEqual(
19+
expect.objectContaining({
20+
size: '0',
21+
shard_size: '0',
22+
})
23+
);
24+
});
25+
});

src/QueryBuilder/elastic.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ export function getDataQuery(queryDef: TermsQuery, refId: string): Elasticsearch
5858

5959
const bucketAggs: BucketAggregation[] = [];
6060
if (queryDef.field) {
61-
bucketAggs.push(getTermsAgg(queryDef.field, 100, 100, orderBy, order))
61+
const size = queryDef.size ?? 100;
62+
bucketAggs.push(getTermsAgg(queryDef.field, size, size, orderBy, order))
6263
}
6364

6465
return {

src/configuration/ConfigEditor.tsx

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import React, { useCallback } from 'react';
2-
import { DataSourceHttpSettings, Input, InlineField, FieldSet } from '@grafana/ui';
3-
import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data';
4-
import { QuickwitOptions } from '../quickwit';
2+
import { DataSourceHttpSettings, Input, InlineField, FieldSet, RadioButtonGroup } from '@grafana/ui';
3+
import { DataSourcePluginOptionsEditorProps, DataSourceSettings, SelectableValue } from '@grafana/data';
4+
import { FilterAutocompleteChainMode, QuickwitOptions } from '../quickwit';
55
import { coerceOptions } from './utils';
66
import { Divider } from '../components/Divider';
77
import { DataLinks } from './DataLinks';
88
import _ from 'lodash';
99

1010
interface Props extends DataSourcePluginOptionsEditorProps<QuickwitOptions> {}
1111

12+
const filterChainModeOptions: Array<SelectableValue<FilterAutocompleteChainMode>> = [
13+
{ label: 'No chain', value: 'none' },
14+
{ label: 'Sample', value: 'sample' },
15+
{ label: 'Full', value: 'full' },
16+
];
17+
1218
export const ConfigEditor = (props: Props) => {
1319
const { options: originalOptions, onOptionsChange } = props;
1420
const options = coerceOptions(originalOptions);
@@ -103,6 +109,47 @@ export const QuickwitDetails = ({ value, onChange }: DetailsProps) => {
103109
width={40}
104110
/>
105111
</InlineField>
112+
<InlineField
113+
label="Filter autocomplete limit"
114+
labelWidth={26}
115+
tooltip="Maximum number of values returned for filter autocomplete. Use 0 for no terms limit."
116+
>
117+
<Input
118+
id="quickwit_filter_autocomplete_limit"
119+
type="number"
120+
min={0}
121+
value={value.jsonData.filterAutocompleteLimit}
122+
onChange={(event) =>
123+
onChange({
124+
...value,
125+
jsonData: { ...value.jsonData, filterAutocompleteLimit: event.currentTarget.value },
126+
})
127+
}
128+
placeholder="1000"
129+
width={40}
130+
/>
131+
</InlineField>
132+
<InlineField
133+
label="Filter chain mode"
134+
labelWidth={26}
135+
tooltip="Controls whether earlier filters narrow later autocomplete suggestions. Sample is fast and approximate for field names; Full scans all matching documents and can be slower."
136+
>
137+
<RadioButtonGroup
138+
id="quickwit_filter_autocomplete_chains"
139+
options={filterChainModeOptions}
140+
value={value.jsonData.filterAutocompleteChainMode}
141+
onChange={(mode) =>
142+
onChange({
143+
...value,
144+
jsonData: {
145+
...value.jsonData,
146+
filterAutocompleteChainMode: mode,
147+
filterAutocompleteUseFilterChains: mode !== 'none',
148+
},
149+
})
150+
}
151+
/>
152+
</InlineField>
106153
</FieldSet>
107154
</div>
108155
</>

src/configuration/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ import { QuickwitOptions } from 'quickwit';
44
export const coerceOptions = (
55
options: DataSourceSettings<QuickwitOptions, {}>
66
): DataSourceSettings<QuickwitOptions, {}> => {
7+
const filterAutocompleteChainMode =
8+
options.jsonData.filterAutocompleteChainMode ??
9+
(options.jsonData.filterAutocompleteUseFilterChains === false ? 'none' : 'sample');
10+
711
return {
812
...options,
913
jsonData: {
1014
...options.jsonData,
1115
logMessageField: options.jsonData.logMessageField || '',
1216
logLevelField: options.jsonData.logLevelField || '',
17+
filterAutocompleteLimit: options.jsonData.filterAutocompleteLimit ?? '1000',
18+
filterAutocompleteChainMode,
19+
filterAutocompleteUseFilterChains: filterAutocompleteChainMode !== 'none',
1320
},
1421
};
1522
};

0 commit comments

Comments
 (0)