mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Fixes KQL autocomplete suggestions with IP fields (#154111)
## Summary Resolves https://github.com/elastic/kibana/issues/140266. Fixes KQL autocomplete suggestions when using an IP field. (Only works when the selected value suggestion method is terms_enum, not terms_agg.) ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### Release note KQL autocomplete suggestions now support IP-type fields when the advanced setting, autocomplete:valueSuggestionMethod, is set to terms_enum. --------- Co-authored-by: Julia Rechkunova <julia.rechkunova@gmail.com>
This commit is contained in:
parent
1384a44eed
commit
c7114d2caa
8 changed files with 55 additions and 16 deletions
|
@ -504,7 +504,7 @@ export function getUiSettings(
|
|||
'The method used for querying suggestions for values in KQL autocomplete. Select terms_enum to use the ' +
|
||||
'Elasticsearch terms enum API for improved autocomplete suggestion performance. (Note that terms_enum is ' +
|
||||
'incompatible with Document Level Security.) Select terms_agg to use an Elasticsearch terms aggregation. ' +
|
||||
'{learnMoreLink}',
|
||||
'(Note that terms_agg is incompatible with IP-type fields.) {learnMoreLink}',
|
||||
values: {
|
||||
learnMoreLink:
|
||||
`<a href=${docLinks.links.kibana.autocompleteSuggestions} target="_blank" rel="noopener">` +
|
||||
|
|
|
@ -69,15 +69,20 @@ describe('FieldSuggestions', () => {
|
|||
expect(http.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return an empty array if the field type is not a string or boolean', async () => {
|
||||
const [field] = stubFields.filter(({ type }) => type !== 'string' && type !== 'boolean');
|
||||
const suggestions = await getValueSuggestions({
|
||||
indexPattern: stubIndexPattern,
|
||||
field,
|
||||
query: '',
|
||||
});
|
||||
|
||||
expect(suggestions).toEqual([]);
|
||||
it('should return an empty array if the field type is not a string, boolean, or IP', async () => {
|
||||
const fields = stubFields.filter(
|
||||
({ type }) => type !== 'string' && type !== 'boolean' && type !== 'ip'
|
||||
);
|
||||
await Promise.all(
|
||||
fields.map(async (field) => {
|
||||
const suggestions = await getValueSuggestions({
|
||||
indexPattern: stubIndexPattern,
|
||||
field,
|
||||
query: '',
|
||||
});
|
||||
expect(suggestions).toEqual([]);
|
||||
})
|
||||
);
|
||||
expect(http.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -93,7 +98,7 @@ describe('FieldSuggestions', () => {
|
|||
expect(http.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should otherwise request suggestions', async () => {
|
||||
it('should request suggestions for strings', async () => {
|
||||
const [field] = stubFields.filter(
|
||||
({ type, aggregatable }) => type === 'string' && aggregatable
|
||||
);
|
||||
|
@ -108,6 +113,19 @@ describe('FieldSuggestions', () => {
|
|||
expect(http.fetch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should request suggestions for ips', async () => {
|
||||
const [field] = stubFields.filter(({ type, aggregatable }) => type === 'ip' && aggregatable);
|
||||
|
||||
await getValueSuggestions({
|
||||
indexPattern: stubIndexPattern,
|
||||
field,
|
||||
query: '',
|
||||
useTimeRange: false,
|
||||
});
|
||||
|
||||
expect(http.fetch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should cache results if using the same index/field/query/filter', async () => {
|
||||
const [field] = stubFields.filter(
|
||||
({ type, aggregatable }) => type === 'string' && aggregatable
|
||||
|
|
|
@ -107,7 +107,7 @@ export const setupValueSuggestionProvider = (
|
|||
} else if (
|
||||
!shouldSuggestValues ||
|
||||
!field.aggregatable ||
|
||||
field.type !== 'string' ||
|
||||
(field.type !== 'string' && field.type !== 'ip') ||
|
||||
isVersionFieldType // suggestions don't work for version fields
|
||||
) {
|
||||
return [];
|
||||
|
|
|
@ -10,7 +10,7 @@ import { coreMock } from '@kbn/core/server/mocks';
|
|||
import { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import { ConfigSchema } from '../../config';
|
||||
import type { DeeplyMockedKeys } from '@kbn/utility-types-jest';
|
||||
import type { DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import type { DataViewField, FieldSpec } from '@kbn/data-views-plugin/common';
|
||||
import { termsAggSuggestions } from './terms_agg';
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { duration } from 'moment';
|
||||
|
@ -136,4 +136,23 @@ describe('terms agg suggestions', () => {
|
|||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('does not call the _search API when the field is an IP', async () => {
|
||||
const result = await termsAggSuggestions(
|
||||
configMock,
|
||||
savedObjectsClientMock,
|
||||
esClientMock,
|
||||
'index',
|
||||
'fieldName',
|
||||
'query',
|
||||
[],
|
||||
{
|
||||
type: 'ip',
|
||||
name: 'fieldName',
|
||||
} as FieldSpec
|
||||
);
|
||||
|
||||
expect(esClientMock.search).not.toHaveBeenCalled();
|
||||
expect(result).toMatchInlineSnapshot(`Array []`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -36,6 +36,11 @@ export async function termsAggSuggestions(
|
|||
field = indexPattern && getFieldByName(fieldName, indexPattern);
|
||||
}
|
||||
|
||||
// Terms agg doesn't support IP with "exclude"/"include" parameter
|
||||
if (field?.type === 'ip') {
|
||||
return [];
|
||||
}
|
||||
|
||||
const body = await getBody(autocompleteSearchOptions, field ?? fieldName, query, filters);
|
||||
|
||||
const result = await esClient.search(
|
||||
|
|
|
@ -1228,7 +1228,6 @@
|
|||
"dashboard.topNave.viewConfigDescription": "Basculer en mode Affichage uniquement",
|
||||
"dashboard.unsavedChangesBadge": "Modifications non enregistrées",
|
||||
"data.advancedSettings.autocompleteIgnoreTimerangeText": "Désactivez cette propriété pour obtenir des suggestions de saisie semi-automatique depuis l'intégralité de l'ensemble de données plutôt que depuis la plage temporelle définie. {learnMoreLink}",
|
||||
"data.advancedSettings.autocompleteValueSuggestionMethodText": "La méthode utilisée pour générer des suggestions de valeur pour la saisie semi-automatique KQL. Sélectionnez terms_enum pour utiliser l'API d'énumération de termes d'Elasticsearch afin d’améliorer les performances de suggestion de saisie semi-automatique. (Notez que terms_enum est incompatible avec la sécurité au niveau du document.) Sélectionnez terms_agg pour utiliser l'agrégation de termes d'Elasticsearch. {learnMoreLink}",
|
||||
"data.advancedSettings.courier.customRequestPreferenceText": "{requestPreferenceLink} utilisé quand {setRequestReferenceSetting} est défini sur {customSettingValue}.",
|
||||
"data.advancedSettings.courier.maxRequestsText": "Contrôle le paramètre {maxRequestsLink} utilisé pour les requêtes _msearch envoyées par Kibana. Définir ce paramètre sur 0 permet d’utiliser la valeur Elasticsearch par défaut.",
|
||||
"data.advancedSettings.query.allowWildcardsText": "Lorsque ce paramètre est activé, le caractère \"*\" est autorisé en tant que premier caractère dans une clause de requête. Pour interdire l'utilisation de caractères génériques au début des requêtes Lucene de base, utilisez {queryStringOptionsPattern}.",
|
||||
|
|
|
@ -1228,7 +1228,6 @@
|
|||
"dashboard.topNave.viewConfigDescription": "表示専用モードに切り替え",
|
||||
"dashboard.unsavedChangesBadge": "保存されていない変更",
|
||||
"data.advancedSettings.autocompleteIgnoreTimerangeText": "このプロパティを無効にすると、現在の時間範囲からではなく、データセットからオートコンプリートの候補を取得します。{learnMoreLink}",
|
||||
"data.advancedSettings.autocompleteValueSuggestionMethodText": "KQL自動入力で値の候補をクエリするために使用される方法。terms_enumを選択すると、Elasticsearch用語enum APIを使用して、自動入力候補のパフォーマンスを改善します。(terms_enumはドキュメントレベルのセキュリティと互換性がありません。) terms_aggを選択すると、Elasticsearch用語アグリゲーションを使用します。{learnMoreLink}",
|
||||
"data.advancedSettings.courier.customRequestPreferenceText": "{setRequestReferenceSetting}が{customSettingValue}に設定されているときに使用される{requestPreferenceLink}です。",
|
||||
"data.advancedSettings.courier.maxRequestsText": "Kibanaから送信された_msearch requestsリクエストに使用される{maxRequestsLink}設定を管理します。この構成を無効にしてElasticsearchのデフォルトを使用するには、0に設定します。",
|
||||
"data.advancedSettings.query.allowWildcardsText": "設定すると、クエリ句の頭に*が使えるようになります。基本的なLuceneクエリでリーディングワイルドカードを無効にするには、{queryStringOptionsPattern}を使用します。",
|
||||
|
|
|
@ -1228,7 +1228,6 @@
|
|||
"dashboard.topNave.viewConfigDescription": "切换到仅查看模式",
|
||||
"dashboard.unsavedChangesBadge": "未保存的更改",
|
||||
"data.advancedSettings.autocompleteIgnoreTimerangeText": "禁用此属性可从您的完全数据集中获取自动完成建议,而非从当前时间范围。{learnMoreLink}",
|
||||
"data.advancedSettings.autocompleteValueSuggestionMethodText": "用于在 KQL 自动完成中查询值建议的方法。选择 terms_enum 以使用 Elasticsearch 字词枚举 API 改善自动完成建议性能。(请注意,terms_enum 不兼容文档级别安全性。) 选择 terms_agg 以使用 Elasticsearch 字词聚合。{learnMoreLink}",
|
||||
"data.advancedSettings.courier.customRequestPreferenceText": "将“{setRequestReferenceSetting}设置为“{customSettingValue}时,将使用“{requestPreferenceLink}”。",
|
||||
"data.advancedSettings.courier.maxRequestsText": "控制用于 Kibana 发送的 _msearch 请求的“{maxRequestsLink}”设置。设置为 0 可禁用此配置并使用 Elasticsearch 默认值。",
|
||||
"data.advancedSettings.query.allowWildcardsText": "设置后,将允许 * 用作查询语句的第一个字符。要在基本 lucene 查询中禁用前导通配符,请使用“{queryStringOptionsPattern}”。",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue