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

[Discover] Use fields API to retrieve fields #83891

Merged
merged 101 commits into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from 72 commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
a232550
Add search source to example plugin.
lukeelmers Oct 27, 2020
ba796e0
Add uiSetting for fields API.
lukeelmers Oct 27, 2020
9fbcc82
Update SearchSource to support fields API.
lukeelmers Oct 27, 2020
5afd264
[PoC] reading from the fields API in Discover
Nov 20, 2020
ac1e273
Add N fields as a default column
Nov 20, 2020
e6f2a22
Make fields column non-removeable
Nov 20, 2020
c420e96
Merge master
Nov 25, 2020
8ad5f99
Do not add 'fields' to state
Nov 25, 2020
64f0868
Remove fields from app state and read from source when needed
Nov 26, 2020
b843d33
Remove fields column if a new column is added
Nov 30, 2020
1a3196d
Add search source to example plugin.
lukeelmers Oct 27, 2020
0cf84e4
Add uiSetting for fields API.
lukeelmers Oct 27, 2020
ad23b7f
Update SearchSource to support fields API.
lukeelmers Oct 27, 2020
3681311
Improve error handling in search examples plugin.
lukeelmers Nov 16, 2020
5ac33bb
Add unit tests for legacy behavior.
lukeelmers Nov 20, 2020
9e6c89f
Remove uiSettings feature flag; add fieldsFromSource config.
lukeelmers Nov 20, 2020
d34ab66
Rewrite flatten() based on final API design.
lukeelmers Nov 20, 2020
4773949
Update example app based on final API design.
lukeelmers Nov 23, 2020
d272609
Update maps app to use legacy fieldsFromSource.
lukeelmers Nov 23, 2020
30c7c5f
Update Discover to use legacy fieldsFromSource.
lukeelmers Nov 23, 2020
24a5f9d
Rename source filters to field filters.
lukeelmers Nov 24, 2020
9c7a967
Address feedback.
lukeelmers Nov 30, 2020
5c124f8
Update generated docs.
lukeelmers Nov 30, 2020
79e59a8
Update maps functional test.
lukeelmers Nov 30, 2020
f7d304b
Formatting fields column similar to _source
Nov 30, 2020
4053bf1
Merge upstream
Dec 1, 2020
ee33143
Moving logic for using search API to updating search source
Dec 1, 2020
e3ace69
Fix small merge error
Dec 1, 2020
84136f6
Merge branch 'master' into feat/ssource-fields
kibanamachine Dec 1, 2020
804c5f8
Merge branch 'feat/ssource-fields' of https://github.com/lukeelmers/k…
Dec 2, 2020
29fe624
Move useSource switch to Discover section of advanced settings
Dec 2, 2020
900637b
Do not use fields and source at the same time
Dec 2, 2020
9fc9517
Remove unmapped fields switch
Dec 2, 2020
92253eb
Add basic support for grouping multifields
Dec 3, 2020
00d6c68
Merge master
Dec 3, 2020
5e6162c
Remove output.txt
Dec 3, 2020
e16cdcb
Fix some merge leftovers
Dec 3, 2020
5e0f998
Fix some merge leftovers
Dec 3, 2020
9791498
Merge branch 'master' into discover-ssource-fields
Dec 3, 2020
63e49d4
Fix merge errors
Dec 3, 2020
a80d44d
Fix typescript errors and update nested fields logic
Dec 4, 2020
60119b9
Add a unit test
Dec 4, 2020
8583723
Fixing field formats
Dec 4, 2020
e21e478
Merge master
Dec 4, 2020
5108654
Fix multifield selection logic
Dec 5, 2020
448bc7a
Request all fields from source
Dec 6, 2020
dc5f148
Fix eslint
Dec 6, 2020
f260376
Fix default columns when switching between _source and fields
Dec 6, 2020
a2273f7
Merge branch 'master' into discover-ssource-fields
Dec 6, 2020
c8c4f47
More unit tests
Dec 6, 2020
57319da
Update API changes
Dec 7, 2020
d07b676
Add unit test for discover field details footer
Dec 7, 2020
50f57ef
Remove unused file
Dec 7, 2020
6990015
Remove fields formatting from index pattern
Dec 8, 2020
0965f30
Remove unnecessary check
Dec 8, 2020
ab4edb4
Addressing design comments
Dec 8, 2020
be9b9f4
Merge branch 'master' into discover-ssource-fields
Dec 8, 2020
1a6c620
Fixing fields column display and renaming it to Document
Dec 9, 2020
95ea135
Adding more unit tests
Dec 9, 2020
fc12250
Adding a missing check for useNewFieldsAPI; minor fixes
Dec 10, 2020
eb309ee
Fixing typescript error
Dec 10, 2020
b7a79d6
Remove unnecessary console statement
Dec 10, 2020
2b63157
Add missing prop
Dec 10, 2020
0f65832
Merge branch 'master' into discover-ssource-fields
kibanamachine Dec 10, 2020
fad95e7
Fixing import order
Dec 11, 2020
d3d38ef
Merge branch 'master' into discover-ssource-fields
kibanamachine Dec 14, 2020
e374d6f
Adding functional test to test fields API
Dec 14, 2020
5efe636
[Functional test] Clean up in after
Dec 14, 2020
24ab2ae
Fixing context app
Dec 15, 2020
88e81f0
Addressing PR comments
Dec 16, 2020
711c757
Merge branch 'master' into discover-ssource-fields
Dec 16, 2020
f03e800
Updating failed snapshot
Dec 16, 2020
0d150e6
Addressing PR comments
Dec 18, 2020
06112da
Fixing i18n translations, updating type
Dec 18, 2020
5eb9917
Addressing PR comments
Dec 18, 2020
b5bfbc0
Merge branch 'master' into discover-ssource-fields
Dec 18, 2020
3ac1ec3
Resolving merge conflicts
Dec 18, 2020
72fd6d5
Updating a functional test
Dec 19, 2020
1e85041
Add a separate functional test for fields API
Dec 19, 2020
1e1d313
Merge branch 'master' into discover-ssource-fields
kibanamachine Dec 19, 2020
88e07b4
Merge branch 'master' into discover-ssource-fields
kibanamachine Dec 21, 2020
e893b93
Read fields from source in a functional test
Dec 21, 2020
b917a39
Skip buggy test
Dec 21, 2020
67606c2
Use default behavior in functional tests
Dec 21, 2020
6ea034e
Fixing remaining failing tests
Dec 21, 2020
5083d44
Fixing date-nanos test
Dec 22, 2020
b1a7158
Updating FLS test
Dec 22, 2020
a16bebd
Merge master
Dec 23, 2020
756d240
Fixing yet another functional test
Dec 23, 2020
64a57df
Skipping non-relevant tests
Dec 24, 2020
f677240
Fixing more tests
Dec 24, 2020
ca8e798
Merge master
Jan 4, 2021
36251a8
Merge branch 'master' into discover-ssource-fields
kibanamachine Jan 11, 2021
8424d71
Merge branch 'master' into discover-ssource-fields
kibanamachine Jan 13, 2021
1caa777
Merge branch 'master' into discover-ssource-fields
Jan 13, 2021
290dfdf
Update stub import in test
Jan 14, 2021
27d77d6
Merge branch 'discover-ssource-fields' of https://github.com/majagrub…
Jan 14, 2021
02c37cf
Fix import
Jan 14, 2021
0eec11a
Fix invalid import
Jan 14, 2021
f1bd9e7
Merge branch 'master' into discover-ssource-fields
kibanamachine Jan 14, 2021
a37612a
Merge branch 'master' into discover-ssource-fields
Jan 15, 2021
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
1 change: 1 addition & 0 deletions src/plugins/discover/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ export const CONTEXT_DEFAULT_SIZE_SETTING = 'context:defaultSize';
export const CONTEXT_STEP_SETTING = 'context:step';
export const CONTEXT_TIE_BREAKER_FIELDS_SETTING = 'context:tieBreakerFields';
export const MODIFY_COLUMNS_ON_SWITCH = 'discover:modifyColumnsOnSwitch';
export const SEARCH_FIELDS_FROM_SOURCE = 'discover:searchFieldsFromSource';
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export function createSearchSourceStub(hits, timeField) {

searchSourceStub.setParent = sinon.spy(() => searchSourceStub);
searchSourceStub.setField = sinon.spy(() => searchSourceStub);
searchSourceStub.removeField = sinon.spy(() => searchSourceStub);

searchSourceStub.getField = sinon.spy((key) => {
const previousSetCall = searchSourceStub.setField.withArgs(key).lastCall;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import _ from 'lodash';
import { i18n } from '@kbn/i18n';

export function fetchAnchorProvider(indexPatterns, searchSource) {
export function fetchAnchorProvider(indexPatterns, searchSource, useNewFieldsApi = false) {
return async function fetchAnchor(indexPatternId, anchorId, sort) {
const indexPattern = await indexPatterns.get(indexPatternId);
searchSource
Expand All @@ -41,7 +41,10 @@ export function fetchAnchorProvider(indexPatterns, searchSource) {
language: 'lucene',
})
.setField('sort', sort);

if (useNewFieldsApi) {
searchSource.removeField('fieldsFromSource');
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you shortly explain me, in what case we would come here with useNewFieldsApi == true and fieldsFromSource has been set? Looking at the rest of the code, it looks like when we're using this flag, we will always already set the fields instead of the fieldsFromSource?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you enable useNewFieldsApi, then disable it, then enable it again - fieldsFromSource will still be set on search source and the request will include _source fields.

searchSource.setField('fields', ['*']);
}
const response = await searchSource.fetch();

if (_.get(response, ['hits', 'total'], 0) < 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,29 @@ describe('context app', function () {
});
});
});

describe('useNewFields API', () => {
let fetchAnchor;
let searchSourceStub;

beforeEach(() => {
searchSourceStub = createSearchSourceStub([{ _id: 'hit1' }]);
fetchAnchor = fetchAnchorProvider(createIndexPatternsStub(), searchSourceStub, true);
});

it('should request fields if useNewFieldsApi set', function () {
searchSourceStub._stubHits = [{ property1: 'value1' }, { property2: 'value2' }];

return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
]).then(() => {
const setFieldsSpy = searchSourceStub.setField.withArgs('fields');
const removeFieldsSpy = searchSourceStub.removeField.withArgs('fieldsFromSource');
expect(setFieldsSpy.calledOnce).toBe(true);
expect(removeFieldsSpy.calledOnce).toBe(true);
expect(setFieldsSpy.firstCall.args[1]).toEqual(['*']);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,81 @@ describe('context app', function () {
});
});
});

describe('function fetchPredecessors with useNewFieldsApi set', function () {
let fetchPredecessors;
let mockSearchSource;

beforeEach(() => {
mockSearchSource = createContextSearchSourceStub([], '@timestamp', MS_PER_DAY * 8);

setServices({
data: {
search: {
searchSource: {
create: jest.fn().mockImplementation(() => mockSearchSource),
},
},
},
});

fetchPredecessors = (
indexPatternId,
timeField,
sortDir,
timeValIso,
timeValNr,
tieBreakerField,
tieBreakerValue,
size
) => {
const anchor = {
_source: {
[timeField]: timeValIso,
},
sort: [timeValNr, tieBreakerValue],
};

return fetchContextProvider(createIndexPatternsStub(), true).fetchSurroundingDocs(
'predecessors',
indexPatternId,
anchor,
timeField,
tieBreakerField,
sortDir,
size,
[]
);
};
});

it('should perform exactly one query when enough hits are returned', function () {
mockSearchSource._stubHits = [
mockSearchSource._createStubHit(MS_PER_DAY * 3000 + 2),
mockSearchSource._createStubHit(MS_PER_DAY * 3000 + 1),
mockSearchSource._createStubHit(MS_PER_DAY * 3000),
mockSearchSource._createStubHit(MS_PER_DAY * 2000),
mockSearchSource._createStubHit(MS_PER_DAY * 1000),
];

return fetchPredecessors(
'INDEX_PATTERN_ID',
'@timestamp',
'desc',
ANCHOR_TIMESTAMP_3000,
MS_PER_DAY * 3000,
'_doc',
0,
3,
[]
).then((hits) => {
const setFieldsSpy = mockSearchSource.setField.withArgs('fields');
const removeFieldsSpy = mockSearchSource.removeField.withArgs('fieldsFromSource');
expect(mockSearchSource.fetch.calledOnce).toBe(true);
expect(removeFieldsSpy.calledOnce).toBe(true);
expect(setFieldsSpy.calledOnce).toBe(true);
expect(hits).toEqual(mockSearchSource._stubHits.slice(0, 3));
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,81 @@ describe('context app', function () {
});
});
});

describe('function fetchSuccessors with useNewFieldsApi set', function () {
let fetchSuccessors;
let mockSearchSource;

beforeEach(() => {
mockSearchSource = createContextSearchSourceStub([], '@timestamp');

setServices({
data: {
search: {
searchSource: {
create: jest.fn().mockImplementation(() => mockSearchSource),
},
},
},
});

fetchSuccessors = (
indexPatternId,
timeField,
sortDir,
timeValIso,
timeValNr,
tieBreakerField,
tieBreakerValue,
size
) => {
const anchor = {
_source: {
[timeField]: timeValIso,
},
sort: [timeValNr, tieBreakerValue],
};

return fetchContextProvider(createIndexPatternsStub(), true).fetchSurroundingDocs(
'successors',
indexPatternId,
anchor,
timeField,
tieBreakerField,
sortDir,
size,
[]
);
};
});

it('should perform exactly one query when enough hits are returned', function () {
mockSearchSource._stubHits = [
mockSearchSource._createStubHit(MS_PER_DAY * 5000),
mockSearchSource._createStubHit(MS_PER_DAY * 4000),
mockSearchSource._createStubHit(MS_PER_DAY * 3000),
mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 1),
mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 2),
];

return fetchSuccessors(
'INDEX_PATTERN_ID',
'@timestamp',
'desc',
ANCHOR_TIMESTAMP_3000,
MS_PER_DAY * 3000,
'_doc',
0,
3,
[]
).then((hits) => {
expect(mockSearchSource.fetch.calledOnce).toBe(true);
expect(hits).toEqual(mockSearchSource._stubHits.slice(-3));
const setFieldsSpy = mockSearchSource.setField.withArgs('fields');
const removeFieldsSpy = mockSearchSource.removeField.withArgs('fieldsFromSource');
expect(removeFieldsSpy.calledOnce).toBe(true);
expect(setFieldsSpy.calledOnce).toBe(true);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const DAY_MILLIS = 24 * 60 * 60 * 1000;
// look from 1 day up to 10000 days into the past and future
const LOOKUP_OFFSETS = [0, 1, 7, 30, 365, 10000].map((days) => days * DAY_MILLIS);

function fetchContextProvider(indexPatterns: IndexPatternsContract) {
function fetchContextProvider(indexPatterns: IndexPatternsContract, useNewFieldsApi?: boolean) {
return {
fetchSurroundingDocs,
};
Expand Down Expand Up @@ -116,6 +116,10 @@ function fetchContextProvider(indexPatterns: IndexPatternsContract) {
const { data } = getServices();

const searchSource = await data.search.searchSource.create();
if (useNewFieldsApi) {
searchSource.removeField('fieldsFromSource');
searchSource.setField('fields', ['*']);
}
return searchSource
.setParent(undefined)
.setField('index', indexPattern)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,17 @@ import { fetchContextProvider } from '../api/context';
import { getQueryParameterActions } from '../query_parameters';
import { FAILURE_REASONS, LOADING_STATUS } from './index';
import { MarkdownSimple } from '../../../../../../kibana_react/public';
import { SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common';

export function QueryActionsProvider(Promise) {
const { filterManager, indexPatterns, data } = getServices();
const fetchAnchor = fetchAnchorProvider(indexPatterns, data.search.searchSource.createEmpty());
const { fetchSurroundingDocs } = fetchContextProvider(indexPatterns);
const { filterManager, indexPatterns, data, uiSettings } = getServices();
const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE);
const fetchAnchor = fetchAnchorProvider(
indexPatterns,
data.search.searchSource.createEmpty(),
useNewFieldsApi
);
const { fetchSurroundingDocs } = fetchContextProvider(indexPatterns, useNewFieldsApi);
const { setPredecessorCount, setQueryParameters, setSuccessorCount } = getQueryParameterActions(
filterManager,
indexPatterns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@
successor-available="contextApp.state.rows.successors.length"
successor-status="contextApp.state.loadingStatus.successors.status"
on-change-successor-count="contextApp.actions.fetchGivenSuccessorRows"
use-new-fields-api="contextApp.state.useNewFieldsApi"
></context-app-legacy>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
*/

import _ from 'lodash';
import { CONTEXT_STEP_SETTING, CONTEXT_TIE_BREAKER_FIELDS_SETTING } from '../../../common';
import {
CONTEXT_STEP_SETTING,
CONTEXT_TIE_BREAKER_FIELDS_SETTING,
SEARCH_FIELDS_FROM_SOURCE,
} from '../../../common';
import { getAngularModule, getServices } from '../../kibana_services';
import contextAppTemplate from './context_app.html';
import './context/components/action_bar';
Expand Down Expand Up @@ -57,12 +61,14 @@ getAngularModule().directive('contextApp', function ContextApp() {

function ContextAppController($scope, Private) {
const { filterManager, indexPatterns, uiSettings } = getServices();
const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE);
const queryParameterActions = getQueryParameterActions(filterManager, indexPatterns);
const queryActions = Private(QueryActionsProvider);
this.state = createInitialState(
parseInt(uiSettings.get(CONTEXT_STEP_SETTING), 10),
getFirstSortableField(this.indexPattern, uiSettings.get(CONTEXT_TIE_BREAKER_FIELDS_SETTING))
);
this.state.useNewFieldsApi = useNewFieldsApi;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we move this into the createInitialState method above, so it's not the only flag we're setting extra on the state again (also will make typescriptification of this file later easier, since the state object will then always be in the correct shape).


this.actions = _.mapValues(
{
Expand Down
Loading