mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Field list - from indexed array to arrays and maps (#47921)
* make fieldList extend array
This commit is contained in:
parent
4a7f36d6cf
commit
b92faf22b4
49 changed files with 247 additions and 170 deletions
|
@ -17,13 +17,13 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
const longString = Array(200).join('_');
|
||||
|
||||
export function getFakeRowVals(type, id, mapping) {
|
||||
return _.mapValues(mapping, function (f, c) {
|
||||
return c + '_' + type + '_' + id + longString;
|
||||
});
|
||||
return mapping.reduce((collector, field) => {
|
||||
collector[field.name] = `${field.name}_${type}_${id}_${longString}`;
|
||||
return collector;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function getFakeRow(id, mapping) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { Filter, RangeFilter, FILTERS, isRangeFilter, isScriptedRangeFilter } from '@kbn/es-query';
|
||||
import { get, has } from 'lodash';
|
||||
import { SavedObjectNotFound } from '../../../../../../../plugins/kibana_utils/public';
|
||||
import { IndexPatterns, IndexPattern } from '../../../index_patterns';
|
||||
import { IndexPatterns, IndexPattern, Field } from '../../../index_patterns';
|
||||
|
||||
const getFirstRangeKey = (filter: RangeFilter) => filter.range && Object.keys(filter.range)[0];
|
||||
const getRangeByKey = (filter: RangeFilter, key: string) => get(filter, ['range', key]);
|
||||
|
@ -44,9 +44,8 @@ function getParams(filter: RangeFilter, indexPattern?: IndexPattern) {
|
|||
// for example a user might manually edit the url or the index pattern's ID might change due to
|
||||
// external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback
|
||||
// on displaying the raw value if the index is invalid.
|
||||
if (key && indexPattern && indexPattern.fields.byName[key]) {
|
||||
const convert = indexPattern.fields.byName[key].format.getConverterFor('text');
|
||||
|
||||
if (key && indexPattern && indexPattern.fields.getByName(key)) {
|
||||
const convert = (indexPattern.fields.getByName(key) as Field).format.getConverterFor('text');
|
||||
value = `${convert(left)} to ${convert(right)}`;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export class StubIndexPatterns {
|
|||
async get(index: string) {
|
||||
return {
|
||||
fields: {
|
||||
byName: {},
|
||||
getByName: () => undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ export { FilterBar, ApplyFiltersPopover } from './filter';
|
|||
export {
|
||||
Field,
|
||||
FieldType,
|
||||
FieldListInterface,
|
||||
IndexPattern,
|
||||
IndexPatterns,
|
||||
StaticIndexPattern,
|
||||
|
|
|
@ -17,24 +17,69 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import { NotificationsSetup } from 'kibana/public';
|
||||
import { findIndex } from 'lodash';
|
||||
import { IndexPattern } from '../index_patterns';
|
||||
import { Field, FieldSpec } from './field';
|
||||
import { Field, FieldType, FieldSpec } from './field';
|
||||
|
||||
export class FieldList extends IndexedArray<Field> {
|
||||
type FieldMap = Map<Field['name'], Field>;
|
||||
|
||||
export interface FieldListInterface extends Array<Field> {
|
||||
getByName(name: Field['name']): Field | undefined;
|
||||
getByType(type: Field['type']): Field[];
|
||||
add(field: FieldSpec): void;
|
||||
remove(field: FieldType): void;
|
||||
}
|
||||
|
||||
export class FieldList extends Array<Field> implements FieldListInterface {
|
||||
private byName: FieldMap = new Map();
|
||||
private groups: Map<Field['type'], FieldMap> = new Map();
|
||||
private indexPattern: IndexPattern;
|
||||
private shortDotsEnable: boolean;
|
||||
private notifications: NotificationsSetup;
|
||||
private setByName = (field: Field) => this.byName.set(field.name, field);
|
||||
private setByGroup = (field: Field) => {
|
||||
if (typeof this.groups.get(field.type) === 'undefined') {
|
||||
this.groups.set(field.type, new Map());
|
||||
}
|
||||
this.groups.get(field.type)!.set(field.name, field);
|
||||
};
|
||||
private removeByGroup = (field: FieldType) => this.groups.get(field.type)!.delete(field.name);
|
||||
constructor(
|
||||
indexPattern: IndexPattern,
|
||||
specs: FieldSpec[],
|
||||
specs: FieldSpec[] = [],
|
||||
shortDotsEnable = false,
|
||||
notifications: NotificationsSetup
|
||||
) {
|
||||
super({
|
||||
index: ['name'],
|
||||
group: ['type'],
|
||||
initialSet: specs.map(function(field) {
|
||||
return new Field(indexPattern, field, shortDotsEnable, notifications);
|
||||
}),
|
||||
});
|
||||
super();
|
||||
this.indexPattern = indexPattern;
|
||||
this.shortDotsEnable = shortDotsEnable;
|
||||
this.notifications = notifications;
|
||||
specs.map(field => this.add(field));
|
||||
}
|
||||
|
||||
getByName = (name: Field['name']) => this.byName.get(name);
|
||||
getByType = (type: Field['type']) => [...(this.groups.get(type) || new Map()).values()];
|
||||
add = (field: FieldSpec) => {
|
||||
const newField = new Field(this.indexPattern, field, this.shortDotsEnable, this.notifications);
|
||||
this.push(newField);
|
||||
this.setByName(newField);
|
||||
this.setByGroup(newField);
|
||||
};
|
||||
|
||||
remove = (field: FieldType) => {
|
||||
this.removeByGroup(field);
|
||||
this.byName.delete(field.name);
|
||||
|
||||
const fieldIndex = findIndex(this, { name: field.name });
|
||||
this.splice(fieldIndex, 1);
|
||||
};
|
||||
|
||||
update = (field: Field) => {
|
||||
const index = this.findIndex(f => f.name === field.name);
|
||||
this.splice(index, 1, field);
|
||||
this.setByName(field);
|
||||
this.removeByGroup(field);
|
||||
this.setByGroup(field);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -27,14 +27,15 @@ function flattenHit(indexPattern: IndexPattern, hit: Record<string, any>, deep:
|
|||
const flat = {} as Record<string, any>;
|
||||
|
||||
// recursively merge _source
|
||||
const fields = indexPattern.fields.byName;
|
||||
const fields = indexPattern.fields.getByName;
|
||||
(function flatten(obj, keyPrefix = '') {
|
||||
keyPrefix = keyPrefix ? keyPrefix + '.' : '';
|
||||
_.forOwn(obj, function(val, key) {
|
||||
key = keyPrefix + key;
|
||||
|
||||
if (deep) {
|
||||
const isNestedField = fields[key] && fields[key].type === 'nested';
|
||||
const field = fields(key);
|
||||
const isNestedField = field && field.type === 'nested';
|
||||
const isArrayOfObjects = Array.isArray(val) && _.isPlainObject(_.first(val));
|
||||
if (isArrayOfObjects && !isNestedField) {
|
||||
_.each(val, v => flatten(v, key));
|
||||
|
@ -44,7 +45,8 @@ function flattenHit(indexPattern: IndexPattern, hit: Record<string, any>, deep:
|
|||
return;
|
||||
}
|
||||
|
||||
const hasValidMapping = fields[key] && fields[key].type !== 'conflict';
|
||||
const field = fields(key);
|
||||
const hasValidMapping = field && field.type !== 'conflict';
|
||||
const isValue = !_.isPlainObject(val);
|
||||
|
||||
if (hasValidMapping || isValue) {
|
||||
|
|
|
@ -27,7 +27,7 @@ const partialFormattedCache = new WeakMap();
|
|||
// returns a formatted version
|
||||
export function formatHitProvider(indexPattern: IndexPattern, defaultFormat: any) {
|
||||
function convert(hit: Record<string, any>, val: any, fieldName: string, type: string = 'html') {
|
||||
const field = indexPattern.fields.byName[fieldName];
|
||||
const field = indexPattern.fields.getByName(fieldName);
|
||||
if (!field) return defaultFormat.convert(val, type);
|
||||
const parsedUrl = {
|
||||
origin: window.location.origin,
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
import { defaults, pluck, last, get } from 'lodash';
|
||||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import { IndexPattern } from './index_pattern';
|
||||
|
||||
import { DuplicateField } from '../../../../../../plugins/kibana_utils/public';
|
||||
|
@ -170,7 +169,6 @@ describe('IndexPattern', () => {
|
|||
test('should append the found fields', () => {
|
||||
expect(savedObjectsClient.get).toHaveBeenCalled();
|
||||
expect(indexPattern.fields).toHaveLength(mockLogStashFields().length);
|
||||
expect(indexPattern.fields).toBeInstanceOf(IndexedArray);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -295,7 +293,9 @@ describe('IndexPattern', () => {
|
|||
const scriptedFields = indexPattern.getScriptedFields();
|
||||
// expect(saveSpy.callCount).to.equal(1);
|
||||
expect(scriptedFields).toHaveLength(oldCount + 1);
|
||||
expect(indexPattern.fields.byName[scriptedField.name].name).toEqual(scriptedField.name);
|
||||
expect((indexPattern.fields.getByName(scriptedField.name) as Field).name).toEqual(
|
||||
scriptedField.name
|
||||
);
|
||||
});
|
||||
|
||||
test('should remove scripted field, by name', async () => {
|
||||
|
@ -304,11 +304,11 @@ describe('IndexPattern', () => {
|
|||
const oldCount = scriptedFields.length;
|
||||
const scriptedField = last(scriptedFields);
|
||||
|
||||
await indexPattern.removeScriptedField(scriptedField.name);
|
||||
await indexPattern.removeScriptedField(scriptedField);
|
||||
|
||||
// expect(saveSpy.callCount).to.equal(1);
|
||||
expect(indexPattern.getScriptedFields().length).toEqual(oldCount - 1);
|
||||
expect(indexPattern.fields.byName[scriptedField.name]).toEqual(undefined);
|
||||
expect(indexPattern.fields.getByName(scriptedField.name)).toEqual(undefined);
|
||||
});
|
||||
|
||||
test('should not allow duplicate names', async () => {
|
||||
|
|
|
@ -28,7 +28,7 @@ import { NotificationsSetup, SavedObjectsClientContract } from 'src/core/public'
|
|||
import { SavedObjectNotFound, DuplicateField } from '../../../../../../plugins/kibana_utils/public';
|
||||
|
||||
import { IndexPatternMissingIndices } from '../errors';
|
||||
import { Field, FieldList, FieldType } from '../fields';
|
||||
import { Field, FieldList, FieldType, FieldListInterface } from '../fields';
|
||||
import { createFieldsFetcher } from './_fields_fetcher';
|
||||
import { getRoutes } from '../utils';
|
||||
import { formatHitProvider } from './format_hit';
|
||||
|
@ -63,7 +63,7 @@ export class IndexPattern implements StaticIndexPattern {
|
|||
public type?: string;
|
||||
public fieldFormatMap: any;
|
||||
public typeMeta: any;
|
||||
public fields: FieldList;
|
||||
public fields: FieldListInterface;
|
||||
public timeFieldName: string | undefined;
|
||||
public formatHit: any;
|
||||
public formatField: any;
|
||||
|
@ -211,15 +211,17 @@ export class IndexPattern implements StaticIndexPattern {
|
|||
// Date value returned in "_source" could be in any number of formats
|
||||
// Use a docvalue for each date field to ensure standardized formats when working with date fields
|
||||
// indexPattern.flattenHit will override "_source" values when the same field is also defined in "fields"
|
||||
const docvalueFields = reject(this.fields.byType.date, 'scripted').map((dateField: any) => {
|
||||
return {
|
||||
field: dateField.name,
|
||||
format:
|
||||
dateField.esTypes && dateField.esTypes.indexOf('date_nanos') !== -1
|
||||
? 'strict_date_time'
|
||||
: 'date_time',
|
||||
};
|
||||
});
|
||||
const docvalueFields = reject(this.fields.getByType('date'), 'scripted').map(
|
||||
(dateField: any) => {
|
||||
return {
|
||||
field: dateField.name,
|
||||
format:
|
||||
dateField.esTypes && dateField.esTypes.indexOf('date_nanos') !== -1
|
||||
? 'strict_date_time'
|
||||
: 'date_time',
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
each(this.getScriptedFields(), function(field) {
|
||||
scriptFields[field.name] = {
|
||||
|
@ -275,7 +277,7 @@ export class IndexPattern implements StaticIndexPattern {
|
|||
throw new DuplicateField(name);
|
||||
}
|
||||
|
||||
this.fields.push(
|
||||
this.fields.add(
|
||||
new Field(
|
||||
this,
|
||||
{
|
||||
|
@ -296,21 +298,13 @@ export class IndexPattern implements StaticIndexPattern {
|
|||
await this.save();
|
||||
}
|
||||
|
||||
removeScriptedField(name: string) {
|
||||
const fieldIndex = _.findIndex(this.fields, {
|
||||
name,
|
||||
scripted: true,
|
||||
});
|
||||
|
||||
if (fieldIndex > -1) {
|
||||
this.fields.splice(fieldIndex, 1);
|
||||
delete this.fieldFormatMap[name];
|
||||
return this.save();
|
||||
}
|
||||
removeScriptedField(field: FieldType) {
|
||||
this.fields.remove(field);
|
||||
return this.save();
|
||||
}
|
||||
|
||||
async popularizeField(fieldName: string, unit = 1) {
|
||||
const field = this.fields.byName[fieldName];
|
||||
const field = this.fields.getByName(fieldName);
|
||||
if (!field) {
|
||||
return;
|
||||
}
|
||||
|
@ -344,13 +338,13 @@ export class IndexPattern implements StaticIndexPattern {
|
|||
}
|
||||
|
||||
getTimeField() {
|
||||
if (!this.timeFieldName || !this.fields || !this.fields.byName) return;
|
||||
return this.fields.byName[this.timeFieldName];
|
||||
if (!this.timeFieldName || !this.fields || !this.fields.getByName) return;
|
||||
return this.fields.getByName(this.timeFieldName);
|
||||
}
|
||||
|
||||
getFieldByName(name: string): Field | void {
|
||||
if (!this.fields || !this.fields.byName) return;
|
||||
return this.fields.byName[name];
|
||||
if (!this.fields || !this.fields.getByName) return;
|
||||
return this.fields.getByName(name);
|
||||
}
|
||||
|
||||
isWildcard() {
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
HttpServiceBase,
|
||||
NotificationsSetup,
|
||||
} from 'src/core/public';
|
||||
import { Field, FieldList, FieldType } from './fields';
|
||||
import { Field, FieldList, FieldListInterface, FieldType } from './fields';
|
||||
import { createFlattenHitWrapper } from './index_patterns';
|
||||
import { createIndexPatternSelect } from './components';
|
||||
import {
|
||||
|
@ -107,4 +107,4 @@ export type IndexPatternsSetup = ReturnType<IndexPatternsService['setup']>;
|
|||
export type IndexPatternsStart = ReturnType<IndexPatternsService['start']>;
|
||||
|
||||
/** @public */
|
||||
export { IndexPattern, IndexPatterns, StaticIndexPattern, Field, FieldType };
|
||||
export { IndexPattern, IndexPatterns, StaticIndexPattern, Field, FieldType, FieldListInterface };
|
||||
|
|
|
@ -33,7 +33,7 @@ export class FilterManager {
|
|||
}
|
||||
|
||||
getField() {
|
||||
return this.indexPattern.fields.byName[this.fieldName];
|
||||
return this.indexPattern.fields.getByName(this.fieldName);
|
||||
}
|
||||
|
||||
createFilter() {
|
||||
|
|
|
@ -38,12 +38,12 @@ export class PhraseFilterManager extends FilterManager {
|
|||
let newFilter;
|
||||
if (phrases.length === 1) {
|
||||
newFilter = buildPhraseFilter(
|
||||
this.indexPattern.fields.byName[this.fieldName],
|
||||
this.indexPattern.fields.getByName(this.fieldName),
|
||||
phrases[0],
|
||||
this.indexPattern);
|
||||
} else {
|
||||
newFilter = buildPhrasesFilter(
|
||||
this.indexPattern.fields.byName[this.fieldName],
|
||||
this.indexPattern.fields.getByName(this.fieldName),
|
||||
phrases,
|
||||
this.indexPattern);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,9 @@ describe('PhraseFilterManager', function () {
|
|||
const indexPatternMock = {
|
||||
id: indexPatternId,
|
||||
fields: {
|
||||
byName: {
|
||||
field1: fieldMock
|
||||
getByName: name => {
|
||||
const fields = { field1: fieldMock };
|
||||
return fields[name];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -56,7 +56,7 @@ export class RangeFilterManager extends FilterManager {
|
|||
*/
|
||||
createFilter(value) {
|
||||
const newFilter = buildRangeFilter(
|
||||
this.indexPattern.fields.byName[this.fieldName],
|
||||
this.indexPattern.fields.getByName(this.fieldName),
|
||||
toRange(value),
|
||||
this.indexPattern);
|
||||
newFilter.meta.key = this.fieldName;
|
||||
|
|
|
@ -32,8 +32,11 @@ describe('RangeFilterManager', function () {
|
|||
const indexPatternMock = {
|
||||
id: indexPatternId,
|
||||
fields: {
|
||||
byName: {
|
||||
field1: fieldMock
|
||||
getByName: name => {
|
||||
const fields = {
|
||||
field1: fieldMock
|
||||
};
|
||||
return fields[name];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -110,7 +110,7 @@ class ListControl extends Control {
|
|||
terminate_after: chrome.getInjected('autocompleteTerminateAfter')
|
||||
};
|
||||
const aggs = termsAgg({
|
||||
field: indexPattern.fields.byName[fieldName],
|
||||
field: indexPattern.fields.getByName(fieldName),
|
||||
size: this.options.dynamicOptions ? null : _.get(this.options, 'size', 5),
|
||||
direction: 'desc',
|
||||
query
|
||||
|
|
|
@ -29,7 +29,10 @@ jest.mock('../../../../core_plugins/data/public/legacy', () => ({
|
|||
indexPatterns: {
|
||||
indexPatterns: {
|
||||
get: () => ({
|
||||
fields: { byName: { myField: { name: 'myField' } } }
|
||||
fields: { getByName: name => {
|
||||
const fields = { myField: { name: 'myField' } };
|
||||
return fields[name];
|
||||
} }
|
||||
}),
|
||||
}
|
||||
},
|
||||
|
@ -37,7 +40,10 @@ jest.mock('../../../../core_plugins/data/public/legacy', () => ({
|
|||
filterManager: {
|
||||
fieldName: 'myNumberField',
|
||||
getIndexPattern: () => ({
|
||||
fields: { byName: { myField: { name: 'myField' } } }
|
||||
fields: { getByName: name => {
|
||||
const fields = { myField: { name: 'myField' } };
|
||||
return fields[name];
|
||||
} }
|
||||
}),
|
||||
getAppFilters: jest.fn().mockImplementation(() => ([])),
|
||||
getGlobalFilters: jest.fn().mockImplementation(() => ([])),
|
||||
|
|
|
@ -64,7 +64,7 @@ class RangeControl extends Control {
|
|||
|
||||
const fieldName = this.filterManager.fieldName;
|
||||
|
||||
const aggs = minMaxAgg(indexPattern.fields.byName[fieldName]);
|
||||
const aggs = minMaxAgg(indexPattern.fields.getByName(fieldName));
|
||||
const searchSource = createSearchSource(this.kbnApi, null, indexPattern, aggs, this.useTimeFilter);
|
||||
this.abortController.signal.addEventListener('abort', () => searchSource.cancelQueued());
|
||||
|
||||
|
|
|
@ -37,16 +37,22 @@ jest.mock('../../../../core_plugins/data/public/legacy', () => ({
|
|||
indexPatterns: {
|
||||
indexPatterns: {
|
||||
get: () => ({
|
||||
fields: { byName: { myNumberField: { name: 'myNumberField' } } }
|
||||
}),
|
||||
fields: { getByName: name => {
|
||||
const fields = { myNumberField: { name: 'myNumberField' } };
|
||||
return fields[name];
|
||||
}
|
||||
} }),
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
filterManager: {
|
||||
fieldName: 'myNumberField',
|
||||
getIndexPattern: () => ({
|
||||
fields: { byName: { myNumberField: { name: 'myNumberField' } } }
|
||||
}),
|
||||
fields: { getByName: name => {
|
||||
const fields = { myNumberField: { name: 'myNumberField' } };
|
||||
return fields[name];
|
||||
}
|
||||
} }),
|
||||
getAppFilters: jest.fn().mockImplementation(() => ([])),
|
||||
getGlobalFilters: jest.fn().mockImplementation(() => ([])),
|
||||
}
|
||||
|
|
|
@ -27,37 +27,40 @@ import { DocViewTable } from './table';
|
|||
// @ts-ignore
|
||||
const indexPattern = {
|
||||
fields: {
|
||||
byName: {
|
||||
_index: {
|
||||
name: '_index',
|
||||
type: 'string',
|
||||
scripted: false,
|
||||
filterable: true,
|
||||
},
|
||||
message: {
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
scripted: false,
|
||||
filterable: false,
|
||||
},
|
||||
extension: {
|
||||
name: 'extension',
|
||||
type: 'string',
|
||||
scripted: false,
|
||||
filterable: true,
|
||||
},
|
||||
bytes: {
|
||||
name: 'bytes',
|
||||
type: 'number',
|
||||
scripted: false,
|
||||
filterable: true,
|
||||
},
|
||||
scripted: {
|
||||
name: 'scripted',
|
||||
type: 'number',
|
||||
scripted: true,
|
||||
filterable: false,
|
||||
},
|
||||
getByName: (name: string) => {
|
||||
const fields: { [name: string]: {} } = {
|
||||
_index: {
|
||||
name: '_index',
|
||||
type: 'string',
|
||||
scripted: false,
|
||||
filterable: true,
|
||||
},
|
||||
message: {
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
scripted: false,
|
||||
filterable: false,
|
||||
},
|
||||
extension: {
|
||||
name: 'extension',
|
||||
type: 'string',
|
||||
scripted: false,
|
||||
filterable: true,
|
||||
},
|
||||
bytes: {
|
||||
name: 'bytes',
|
||||
type: 'number',
|
||||
scripted: false,
|
||||
filterable: true,
|
||||
},
|
||||
scripted: {
|
||||
name: 'scripted',
|
||||
type: 'number',
|
||||
scripted: true,
|
||||
filterable: false,
|
||||
},
|
||||
};
|
||||
return fields[name];
|
||||
},
|
||||
},
|
||||
metaFields: ['_index', '_score'],
|
||||
|
|
|
@ -31,7 +31,7 @@ export function DocViewTable({
|
|||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
}: DocViewRenderProps) {
|
||||
const mapping = indexPattern.fields.byName;
|
||||
const mapping = indexPattern.fields.getByName;
|
||||
const flattened = indexPattern.flattenHit(hit);
|
||||
const formatted = indexPattern.formatHit(hit, 'html');
|
||||
const [fieldRowOpen, setFieldRowOpen] = useState({} as Record<string, boolean>);
|
||||
|
@ -63,15 +63,15 @@ export function DocViewTable({
|
|||
: undefined;
|
||||
const isArrayOfObjects =
|
||||
Array.isArray(flattened[field]) && arrayContainsObjects(flattened[field]);
|
||||
const displayUnderscoreWarning = !mapping[field] && field.indexOf('_') === 0;
|
||||
const displayUnderscoreWarning = !mapping(field) && field.indexOf('_') === 0;
|
||||
const displayNoMappingWarning =
|
||||
!mapping[field] && !displayUnderscoreWarning && !isArrayOfObjects;
|
||||
!mapping(field) && !displayUnderscoreWarning && !isArrayOfObjects;
|
||||
|
||||
return (
|
||||
<DocViewTableRow
|
||||
key={field}
|
||||
field={field}
|
||||
fieldMapping={mapping[field]}
|
||||
fieldMapping={mapping(field)}
|
||||
displayUnderscoreWarning={displayUnderscoreWarning}
|
||||
displayNoMappingWarning={displayNoMappingWarning}
|
||||
isCollapsed={isCollapsed}
|
||||
|
|
|
@ -39,7 +39,7 @@ export function getFirstSortableField(indexPattern: IndexPattern, fieldNames: st
|
|||
fieldName =>
|
||||
META_FIELD_NAMES.includes(fieldName) ||
|
||||
// @ts-ignore
|
||||
(indexPattern.fields.byName[fieldName] || { sortable: false }).sortable
|
||||
(indexPattern.fields.getByName(fieldName) || { sortable: false }).sortable
|
||||
);
|
||||
return sortableFields[0];
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('discoverField', function () {
|
|||
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
|
||||
|
||||
_.assign($rootScope, {
|
||||
field: indexPattern.fields.byName.extension,
|
||||
field: indexPattern.fields.getByName('extension'),
|
||||
addField: sinon.spy(() => $rootScope.field.display = true),
|
||||
removeField: sinon.spy(() => $rootScope.field.display = false),
|
||||
showDetails: sinon.spy(() => $rootScope.field.details = { exists: true }),
|
||||
|
|
|
@ -114,14 +114,14 @@ describe('fieldCalculator', function () {
|
|||
});
|
||||
|
||||
it('Should return an array of values for _source fields', function () {
|
||||
const extensions = fieldCalculator.getFieldValues(hits, indexPattern.fields.byName.extension);
|
||||
const extensions = fieldCalculator.getFieldValues(hits, indexPattern.fields.getByName('extension'));
|
||||
expect(extensions).to.be.an(Array);
|
||||
expect(_.filter(extensions, function (v) { return v === 'html'; }).length).to.be(8);
|
||||
expect(_.uniq(_.clone(extensions)).sort()).to.eql(['gif', 'html', 'php', 'png']);
|
||||
});
|
||||
|
||||
it('Should return an array of values for core meta fields', function () {
|
||||
const types = fieldCalculator.getFieldValues(hits, indexPattern.fields.byName._type);
|
||||
const types = fieldCalculator.getFieldValues(hits, indexPattern.fields.getByName('_type'));
|
||||
expect(types).to.be.an(Array);
|
||||
expect(_.filter(types, function (v) { return v === 'apache'; }).length).to.be(18);
|
||||
expect(_.uniq(_.clone(types)).sort()).to.eql(['apache', 'nginx']);
|
||||
|
@ -134,7 +134,7 @@ describe('fieldCalculator', function () {
|
|||
beforeEach(function () {
|
||||
params = {
|
||||
hits: require('fixtures/real_hits.js'),
|
||||
field: indexPattern.fields.byName.extension,
|
||||
field: indexPattern.fields.getByName('extension'),
|
||||
count: 3
|
||||
};
|
||||
});
|
||||
|
@ -149,18 +149,18 @@ describe('fieldCalculator', function () {
|
|||
});
|
||||
|
||||
it('fails to analyze geo and attachment types', function () {
|
||||
params.field = indexPattern.fields.byName.point;
|
||||
params.field = indexPattern.fields.getByName('point');
|
||||
expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
|
||||
|
||||
params.field = indexPattern.fields.byName.area;
|
||||
params.field = indexPattern.fields.getByName('area');
|
||||
expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
|
||||
|
||||
params.field = indexPattern.fields.byName.request_body;
|
||||
params.field = indexPattern.fields.getByName('request_body');
|
||||
expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
|
||||
});
|
||||
|
||||
it('fails to analyze fields that are in the mapping, but not the hits', function () {
|
||||
params.field = indexPattern.fields.byName.ip;
|
||||
params.field = indexPattern.fields.getByName('ip');
|
||||
expect(fieldCalculator.getFieldValueCounts(params).error).to.not.be(undefined);
|
||||
});
|
||||
|
||||
|
@ -169,7 +169,7 @@ describe('fieldCalculator', function () {
|
|||
});
|
||||
|
||||
it('counts the hits the field exists in', function () {
|
||||
params.field = indexPattern.fields.byName.phpmemory;
|
||||
params.field = indexPattern.fields.getByName('phpmemory');
|
||||
expect(fieldCalculator.getFieldValueCounts(params).exists).to.be(5);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
</div>
|
||||
<ul class="list-unstyled dscFieldList--selected" aria-labelledby="selected_fields">
|
||||
<discover-field
|
||||
ng-repeat="field in fields.raw|filter:filter.isFieldFilteredAndDisplayed"
|
||||
ng-repeat="field in fields|filter:filter.isFieldFilteredAndDisplayed"
|
||||
field="field"
|
||||
on-add-field="onAddField"
|
||||
on-add-filter="onAddFilter"
|
||||
|
|
|
@ -281,7 +281,7 @@ app.directive('discFieldChooser', function ($location, config, $route) {
|
|||
|
||||
const fieldSpecs = indexPattern.fields.slice(0);
|
||||
const fieldNamesInDocs = _.keys(fieldCounts);
|
||||
const fieldNamesInIndexPattern = _.keys(indexPattern.fields.byName);
|
||||
const fieldNamesInIndexPattern = _.map(indexPattern.fields, 'name');
|
||||
|
||||
_.difference(fieldNamesInDocs, fieldNamesInIndexPattern)
|
||||
.forEach(function (unknownFieldName) {
|
||||
|
@ -295,7 +295,7 @@ app.directive('discFieldChooser', function ($location, config, $route) {
|
|||
|
||||
if (prevFields) {
|
||||
fields.forEach(function (field) {
|
||||
field.details = _.get(prevFields, ['byName', field.name, 'details']);
|
||||
field.details = (prevFields.getByName(field.name) || {}).details;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@ describe('Doc Table', function () {
|
|||
config = _config_;
|
||||
$parentScope = $rootScope;
|
||||
$parentScope.indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
|
||||
mapping = $parentScope.indexPattern.fields.byName;
|
||||
mapping = $parentScope.indexPattern.fields;
|
||||
|
||||
// Stub `getConverterFor` for a field in the indexPattern to return mock data.
|
||||
// Returns `val` if provided, otherwise generates fake data for the field.
|
||||
fakeRowVals = getFakeRowVals('formatted', 0, mapping);
|
||||
stubFieldFormatConverter = function ($root, field, val = null) {
|
||||
$root.indexPattern.fields.byName[field].format.getConverterFor = () => (...args) => {
|
||||
$root.indexPattern.fields.getByName(field).format.getConverterFor = () => (...args) => {
|
||||
if (val) {
|
||||
return val;
|
||||
}
|
||||
|
@ -252,8 +252,8 @@ describe('Doc Table', function () {
|
|||
$root.indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
|
||||
|
||||
// Stub field format converters for every field in the indexPattern
|
||||
Object.keys($root.indexPattern.fields.byName).forEach(f =>
|
||||
stubFieldFormatConverter($root, f)
|
||||
$root.indexPattern.fields.forEach(f =>
|
||||
stubFieldFormatConverter($root, f.name)
|
||||
);
|
||||
|
||||
$row = $('<tr>').attr({
|
||||
|
|
|
@ -104,7 +104,7 @@ module.directive('kbnTableRow', function ($compile, $httpParamSerializer, kbnUrl
|
|||
|
||||
$scope.inlineFilter = function inlineFilter($event, type) {
|
||||
const column = $($event.target).data().column;
|
||||
const field = $scope.indexPattern.fields.byName[column];
|
||||
const field = $scope.indexPattern.fields.getByName(column);
|
||||
$scope.filter(field, $scope.flattenedRow[column], type);
|
||||
};
|
||||
|
||||
|
@ -130,7 +130,7 @@ module.directive('kbnTableRow', function ($compile, $httpParamSerializer, kbnUrl
|
|||
// We just create a string here because its faster.
|
||||
const newHtmls = [openRowHtml];
|
||||
|
||||
const mapping = indexPattern.fields.byName;
|
||||
const mapping = indexPattern.fields.getByName;
|
||||
const hideTimeColumn = config.get('doc_table:hideTimeColumn');
|
||||
if (indexPattern.timeFieldName && !hideTimeColumn) {
|
||||
newHtmls.push(
|
||||
|
@ -138,7 +138,7 @@ module.directive('kbnTableRow', function ($compile, $httpParamSerializer, kbnUrl
|
|||
timefield: true,
|
||||
formatted: _displayField(row, indexPattern.timeFieldName),
|
||||
filterable:
|
||||
mapping[indexPattern.timeFieldName].filterable && _.isFunction($scope.filter),
|
||||
mapping(indexPattern.timeFieldName).filterable && _.isFunction($scope.filter),
|
||||
column: indexPattern.timeFieldName,
|
||||
})
|
||||
);
|
||||
|
@ -147,8 +147,8 @@ module.directive('kbnTableRow', function ($compile, $httpParamSerializer, kbnUrl
|
|||
$scope.columns.forEach(function (column) {
|
||||
const isFilterable =
|
||||
$scope.flattenedRow[column] !== undefined &&
|
||||
mapping[column] &&
|
||||
mapping[column].filterable &&
|
||||
mapping(column) &&
|
||||
mapping(column).filterable &&
|
||||
_.isFunction($scope.filter);
|
||||
|
||||
newHtmls.push(
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
function isSortable(field, indexPattern) {
|
||||
return (indexPattern.fields.byName[field] && indexPattern.fields.byName[field].sortable);
|
||||
return (indexPattern.fields.getByName(field) && indexPattern.fields.getByName(field).sortable);
|
||||
}
|
||||
|
||||
function createSortObject(sortPair, indexPattern) {
|
||||
|
|
|
@ -50,7 +50,7 @@ describe('_source formatting', function () {
|
|||
|
||||
it('uses the _source, field, and hit to create a <dl>', function () {
|
||||
const hit = _.first(hits);
|
||||
const $nonBindable = $(convertHtml(hit._source, indexPattern.fields.byName._source, hit));
|
||||
const $nonBindable = $(convertHtml(hit._source, indexPattern.fields, hit));
|
||||
expect($nonBindable.is('span[ng-non-bindable]')).to.be.ok();
|
||||
const $dl = $nonBindable.children();
|
||||
expect($dl.is('dl')).to.be.ok();
|
||||
|
|
|
@ -115,7 +115,7 @@ uiRoutes
|
|||
|
||||
if (this.mode === 'edit') {
|
||||
const fieldName = $route.current.params.fieldName;
|
||||
this.field = this.indexPattern.fields.byName[fieldName];
|
||||
this.field = this.indexPattern.fields.getByName(fieldName);
|
||||
|
||||
if (!this.field) {
|
||||
const message = i18n.translate('kbn.management.editIndexPattern.scripted.noFieldLabel',
|
||||
|
|
|
@ -129,7 +129,7 @@ export class ScriptedFieldsTable extends Component {
|
|||
const { indexPattern, onRemoveField } = this.props;
|
||||
const { fieldToDelete } = this.state;
|
||||
|
||||
indexPattern.removeScriptedField(fieldToDelete.name);
|
||||
indexPattern.removeScriptedField(fieldToDelete);
|
||||
onRemoveField && onRemoveField();
|
||||
this.fetchFields();
|
||||
this.hideDeleteConfirmationModal();
|
||||
|
|
|
@ -77,12 +77,12 @@ export default function AggParamWriterHelper(Private) {
|
|||
if (this.aggType.paramByName('field') && !paramValues.field) {
|
||||
// pick a field rather than force a field to be specified everywhere
|
||||
if (this.aggType.type === AggGroupNames.Metrics) {
|
||||
paramValues.field = _.sample(this.indexPattern.fields.byType.number);
|
||||
paramValues.field = _.sample(this.indexPattern.fields.getByType('number'));
|
||||
} else {
|
||||
const type = this.aggType.paramByName('field').filterFieldTypes || 'string';
|
||||
let field;
|
||||
do {
|
||||
field = _.sample(this.indexPattern.fields.byType[type]);
|
||||
field = _.sample(this.indexPattern.fields.getByType(type));
|
||||
} while (!field.aggregatable);
|
||||
paramValues.field = field.name;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('AggConfig Filters', function () {
|
|||
interval = interval || 'auto';
|
||||
if (interval === 'custom') interval = agg.params.customInterval;
|
||||
duration = duration || moment.duration(15, 'minutes');
|
||||
field = _.sample(_.reject(indexPattern.fields.byType.date, 'scripted'));
|
||||
field = _.sample(_.reject(indexPattern.fields.getByType('date'), 'scripted'));
|
||||
vis = new Vis(indexPattern, {
|
||||
type: 'histogram',
|
||||
aggs: [
|
||||
|
|
|
@ -25,7 +25,7 @@ import { FieldParamEditor } from '../../vis/editors/default/controls/field';
|
|||
import { BaseParamType } from './base';
|
||||
import { toastNotifications } from '../../notify';
|
||||
import { propFilter } from '../filter';
|
||||
import { Field } from '../../index_patterns';
|
||||
import { Field, FieldListInterface } from '../../index_patterns';
|
||||
|
||||
const filterByType = propFilter('type');
|
||||
|
||||
|
@ -79,7 +79,7 @@ export class FieldParamType extends BaseParamType {
|
|||
if (!aggConfig) {
|
||||
throw new Error('aggConfig was not provided to FieldParamType deserialize function');
|
||||
}
|
||||
const field = aggConfig.getIndexPattern().fields.byName[fieldName];
|
||||
const field = aggConfig.getIndexPattern().fields.getByName(fieldName);
|
||||
|
||||
if (!field) {
|
||||
throw new SavedObjectNotFound('index-pattern-field', fieldName);
|
||||
|
@ -111,7 +111,7 @@ export class FieldParamType extends BaseParamType {
|
|||
/**
|
||||
* filter the fields to the available ones
|
||||
*/
|
||||
getAvailableFields = (fields: Field[]) => {
|
||||
getAvailableFields = (fields: FieldListInterface) => {
|
||||
const filteredFields = fields.filter((field: Field) => {
|
||||
const { onlyAggregatable, scriptable, filterFieldTypes } = this;
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ describe('SearchSource#normalizeSortRequest', function () {
|
|||
it('should enable script based sorting', function () {
|
||||
const fieldName = 'script string';
|
||||
const direction = 'desc';
|
||||
const indexField = indexPattern.fields.byName[fieldName];
|
||||
const indexField = indexPattern.fields.getByName(fieldName);
|
||||
|
||||
const sortState = {};
|
||||
sortState[fieldName] = direction;
|
||||
|
|
|
@ -42,7 +42,7 @@ export function NormalizeSortRequestProvider(config) {
|
|||
const normalized = {};
|
||||
let sortField = _.keys(sortable)[0];
|
||||
let sortValue = sortable[sortField];
|
||||
const indexField = indexPattern.fields.byName[sortField];
|
||||
const indexField = indexPattern.fields.getByName(sortField);
|
||||
|
||||
if (indexField && indexField.scripted && indexField.sortable) {
|
||||
let direction;
|
||||
|
|
|
@ -148,7 +148,7 @@ export class FieldEditorComponent extends PureComponent {
|
|||
|
||||
this.setState({
|
||||
isReady: true,
|
||||
isCreating: !indexPattern.fields.byName[field.name],
|
||||
isCreating: !indexPattern.fields.getByName(field.name),
|
||||
isDeprecatedLang: this.deprecatedLangs.includes(field.lang),
|
||||
errors: [],
|
||||
scriptingLangs,
|
||||
|
@ -673,7 +673,7 @@ export class FieldEditorComponent extends PureComponent {
|
|||
const { redirectAway } = this.props.helpers;
|
||||
const { indexPattern, intl } = this.props;
|
||||
const { field } = this.state;
|
||||
const remove = indexPattern.removeScriptedField(field.name);
|
||||
const remove = indexPattern.removeScriptedField(field);
|
||||
|
||||
if(remove) {
|
||||
remove.then(() => {
|
||||
|
@ -718,9 +718,9 @@ export class FieldEditorComponent extends PureComponent {
|
|||
const index = indexPattern.fields.findIndex(f => f.name === field.name);
|
||||
|
||||
if (index > -1) {
|
||||
indexPattern.fields.splice(index, 1, field);
|
||||
indexPattern.fields.update(field);
|
||||
} else {
|
||||
indexPattern.fields.push(field);
|
||||
indexPattern.fields.add(field);
|
||||
}
|
||||
|
||||
if (!fieldFormatId) {
|
||||
|
|
|
@ -97,10 +97,13 @@ jest.mock('./components/field_format_editor', () => ({
|
|||
const fields = [{
|
||||
name: 'foobar',
|
||||
}];
|
||||
fields.byName = {
|
||||
foobar: {
|
||||
name: 'foobar',
|
||||
},
|
||||
fields.getByName = name => {
|
||||
const fields = {
|
||||
foobar: {
|
||||
name: 'foobar',
|
||||
},
|
||||
};
|
||||
return fields[name];
|
||||
};
|
||||
|
||||
class Format {
|
||||
|
@ -153,7 +156,12 @@ describe('FieldEditor', () => {
|
|||
script: 'doc.test.value',
|
||||
};
|
||||
indexPattern.fields.push(testField);
|
||||
indexPattern.fields.byName[testField.name] = testField;
|
||||
indexPattern.fields.getByName = (name) => {
|
||||
const fields = {
|
||||
[testField.name]: testField
|
||||
};
|
||||
return fields[name];
|
||||
};
|
||||
|
||||
const component = shallowWithIntl(
|
||||
<FieldEditorComponent
|
||||
|
@ -176,7 +184,12 @@ describe('FieldEditor', () => {
|
|||
lang: 'testlang'
|
||||
};
|
||||
indexPattern.fields.push(testField);
|
||||
indexPattern.fields.byName[testField.name] = testField;
|
||||
indexPattern.fields.getByName = (name) => {
|
||||
const fields = {
|
||||
[testField.name]: testField
|
||||
};
|
||||
return fields[name];
|
||||
};
|
||||
|
||||
const component = shallowWithIntl(
|
||||
<FieldEditorComponent
|
||||
|
|
|
@ -55,6 +55,7 @@ export {
|
|||
export {
|
||||
Field,
|
||||
FieldType,
|
||||
FieldListInterface,
|
||||
IndexPattern,
|
||||
IndexPatterns,
|
||||
StaticIndexPattern,
|
||||
|
|
|
@ -479,7 +479,7 @@ describe('AggConfig', function () {
|
|||
});
|
||||
|
||||
it('returns the html converter if "html" is passed in', function () {
|
||||
const field = indexPattern.fields.byName.bytes;
|
||||
const field = indexPattern.fields.getByName('bytes');
|
||||
expect(vis.aggs.aggs[0].fieldFormatter('html')).to.be(field.format.getConverterFor('html'));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -74,7 +74,7 @@ describe('<Settings />', () => {
|
|||
.simulate('click');
|
||||
|
||||
// Wait for the animation and DOM update
|
||||
await tick(20);
|
||||
await tick(40);
|
||||
portal(wrapper).update();
|
||||
expect(portal(wrapper).html()).toMatchSnapshot();
|
||||
|
||||
|
|
|
@ -138,10 +138,13 @@ describe('hitsToGeoJson', () => {
|
|||
describe('dot in geoFieldName', () => {
|
||||
const indexPatternMock = {
|
||||
fields: {
|
||||
byName: {
|
||||
['my.location']: {
|
||||
type: 'geo_point'
|
||||
}
|
||||
getByName: name => {
|
||||
const fields = {
|
||||
['my.location']: {
|
||||
type: 'geo_point'
|
||||
}
|
||||
};
|
||||
return fields[name];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -261,7 +261,7 @@ export class ESPewPewSource extends AbstractESSource {
|
|||
|
||||
async _getGeoField() {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
const geoField = indexPattern.fields.byName[this._descriptor.destGeoField];
|
||||
const geoField = indexPattern.fields.getByName(this._descriptor.destGeoField);
|
||||
if (!geoField) {
|
||||
throw new Error(i18n.translate('xpack.maps.source.esSource.noGeoFieldErrorMessage', {
|
||||
defaultMessage: `Index pattern {indexPatternTitle} no longer contains the geo field {geoField}`,
|
||||
|
|
|
@ -83,7 +83,7 @@ export class ESSearchSource extends AbstractESSource {
|
|||
async getNumberFields() {
|
||||
try {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
return indexPattern.fields.byType.number.map(field => {
|
||||
return indexPattern.fields.getByType('number').map(field => {
|
||||
return { name: field.name, label: field.name };
|
||||
});
|
||||
} catch (error) {
|
||||
|
@ -163,7 +163,7 @@ export class ESSearchSource extends AbstractESSource {
|
|||
|
||||
const scriptFields = {};
|
||||
searchFilters.fieldNames.forEach(fieldName => {
|
||||
const field = indexPattern.fields.byName[fieldName];
|
||||
const field = indexPattern.fields.getByName(fieldName);
|
||||
if (field && field.scripted) {
|
||||
scriptFields[field.name] = {
|
||||
script: {
|
||||
|
|
|
@ -273,7 +273,7 @@ export class AbstractESSource extends AbstractVectorSource {
|
|||
|
||||
async _getGeoField() {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
const geoField = indexPattern.fields.byName[this._descriptor.geoField];
|
||||
const geoField = indexPattern.fields.getByName(this._descriptor.geoField);
|
||||
if (!geoField) {
|
||||
throw new Error(i18n.translate('xpack.maps.source.esSource.noGeoFieldErrorMessage', {
|
||||
defaultMessage: `Index pattern {indexPatternTitle} no longer contains the geo field {geoField}`,
|
||||
|
|
|
@ -24,7 +24,7 @@ export class ESAggMetricTooltipProperty extends ESTooltipProperty {
|
|||
if (this._metricField.type === 'count') {
|
||||
return this._rawValue;
|
||||
}
|
||||
const indexPatternField = this._indexPattern.fields.byName[this._metricField.field];
|
||||
const indexPatternField = this._indexPattern.fields.getByName(this._metricField.field);
|
||||
if (!indexPatternField) {
|
||||
return this._rawValue;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export class ESTooltipProperty extends TooltipProperty {
|
|||
return '-';
|
||||
}
|
||||
|
||||
const field = this._indexPattern.fields.byName[this._propertyName];
|
||||
const field = this._indexPattern.fields.getByName(this._propertyName);
|
||||
if (!field) {
|
||||
return _.escape(this._rawValue);
|
||||
}
|
||||
|
@ -30,14 +30,14 @@ export class ESTooltipProperty extends TooltipProperty {
|
|||
}
|
||||
|
||||
isFilterable() {
|
||||
const field = this._indexPattern.fields.byName[this._propertyName];
|
||||
const field = this._indexPattern.fields.getByName(this._propertyName);
|
||||
return field && (field.type === 'string' || field.type === 'date' || field.type === 'ip' || field.type === 'number');
|
||||
}
|
||||
|
||||
async getESFilters() {
|
||||
return [
|
||||
buildPhraseFilter(
|
||||
this._indexPattern.fields.byName[this._propertyName],
|
||||
this._indexPattern.fields.getByName(this._propertyName),
|
||||
this._rawValue,
|
||||
this._indexPattern)
|
||||
];
|
||||
|
|
|
@ -79,7 +79,7 @@ class FieldFormatService {
|
|||
// e.g. distinct_count(clientip) should be formatted as a count, not as an IP address.
|
||||
let fieldFormat = undefined;
|
||||
if (esAggName !== 'cardinality') {
|
||||
const indexPatternFields = _.get(fullIndexPattern, 'fields.byName', []);
|
||||
const indexPatternFields = _.get(fullIndexPattern, 'fields', []);
|
||||
fieldFormat = _.get(indexPatternFields, [fieldName, 'format']);
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ class FieldFormatService {
|
|||
getIndexPatternById(indexPatternId)
|
||||
.then((indexPatternData) => {
|
||||
// Store the FieldFormat for each job by detector_index.
|
||||
const fieldsByName = _.get(indexPatternData, 'fields.byName', []);
|
||||
const fieldsByName = _.get(indexPatternData, 'fields', []);
|
||||
_.each(detectors, (dtr) => {
|
||||
const esAgg = mlFunctionToESAggregation(dtr.function);
|
||||
// distinct_count detectors should fall back to the default
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue