[data views] allow fields that start with an underscore in the field list (#111238)

* stop filtering out fields that start with underscore
This commit is contained in:
Matthew Kime 2021-09-13 10:45:34 -05:00 committed by GitHub
parent 3b4d99bcf4
commit 3fd7dbe455
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 53 additions and 8 deletions

View file

@ -57,9 +57,10 @@ describe('flattenHit', () => {
fields: {
date: ['1'],
zzz: ['z'],
_abc: ['a'],
},
});
const expectedOrder = ['date', 'name', 'zzz', '_id', '_routing', '_score', '_type'];
const expectedOrder = ['_abc', 'date', 'name', 'zzz', '_id', '_routing', '_score', '_type'];
expect(Object.keys(response)).toEqual(expectedOrder);
expect(Object.entries(response).map(([key]) => key)).toEqual(expectedOrder);
});

View file

@ -66,7 +66,6 @@ function decorateFlattenedWrapper(hit: Record<string, any>, metaFields: Record<s
// unwrap computed fields
_.forOwn(hit.fields, function (val, key: any) {
if (key[0] === '_' && !_.includes(metaFields, key)) return;
// Flatten an array with 0 or 1 elements to a single value.
if (Array.isArray(val) && val.length <= 1) {
flattened[key] = val[0];

View file

@ -25,6 +25,7 @@ export interface FieldDescriptor {
type: string;
esTypes: string[];
subType?: FieldSubType;
metadata_field?: boolean;
}
interface FieldSubType {

View file

@ -69,6 +69,17 @@ describe('index_patterns/field_capabilities/field_capabilities', () => {
});
describe('response order', () => {
it('supports fields that start with an underscore', async () => {
const fields = ['_field_a', '_field_b'];
stubDeps({
fieldsFromFieldCaps: fields.map((name) => ({ name })),
});
const fieldNames = (await getFieldCapabilities()).map((field) => field.name);
expect(fieldNames).toEqual(fields);
});
it('always returns fields in alphabetical order', async () => {
const letters = 'ambcdfjopngihkel'.split('');
const sortedLetters = sortBy(letters);

View file

@ -34,20 +34,21 @@ export async function getFieldCapabilities(
const fieldsFromFieldCapsByName = keyBy(readFieldCapsResponse(esFieldCaps.body), 'name');
const allFieldsUnsorted = Object.keys(fieldsFromFieldCapsByName)
.filter((name) => !name.startsWith('_'))
// not all meta fields are provided, so remove and manually add
.filter((name) => !fieldsFromFieldCapsByName[name].metadata_field)
.concat(metaFields)
.reduce<{ names: string[]; hash: Record<string, string> }>(
.reduce<{ names: string[]; map: Map<string, string> }>(
(agg, value) => {
// This is intentionally using a "hash" and a "push" to be highly optimized with very large indexes
if (agg.hash[value] != null) {
// This is intentionally using a Map to be highly optimized with very large indexes AND be safe for user provided data
if (agg.map.get(value) != null) {
return agg;
} else {
agg.hash[value] = value;
agg.map.set(value, value);
agg.names.push(value);
return agg;
}
},
{ names: [], hash: {} }
{ names: [], map: new Map<string, string>() }
)
.names.map<FieldDescriptor>((name) =>
defaults({}, fieldsFromFieldCapsByName[name], {
@ -56,6 +57,7 @@ export async function getFieldCapabilities(
searchable: false,
aggregatable: false,
readFromDocValues: false,
metadata_field: metaFields.includes(name),
})
)
.map(mergeOverrides);

View file

@ -48,6 +48,7 @@ describe('index_patterns/field_capabilities/field_caps_response', () => {
'searchable',
'aggregatable',
'readFromDocValues',
'metadata_field',
]);
});
}

View file

@ -116,6 +116,8 @@ export function readFieldCapsResponse(
}),
{}
),
// @ts-expect-error
metadata_field: capsByType[types[0]].metadata_field,
};
// This is intentionally using a "hash" and a "push" to be highly optimized with very large indexes
agg.array.push(field);
@ -131,6 +133,8 @@ export function readFieldCapsResponse(
searchable: isSearchable,
aggregatable: isAggregatable,
readFromDocValues: shouldReadFieldFromDocValues(isAggregatable, esType),
// @ts-expect-error
metadata_field: capsByType[types[0]].metadata_field,
};
// This is intentionally using a "hash" and a "push" to be highly optimized with very large indexes
agg.array.push(field);

View file

@ -38,6 +38,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
{
name: 'Jan01',
@ -46,6 +47,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
{
name: 'Jan02',
@ -54,6 +56,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
],
});
@ -77,6 +80,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
{
name: 'Jan02',
@ -85,6 +89,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
],
});
@ -109,6 +114,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
{
name: 'Jan02',
@ -117,6 +123,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
{
name: 'meta1',
@ -124,6 +131,7 @@ export default function ({ getService }) {
aggregatable: false,
searchable: false,
readFromDocValues: false,
metadata_field: true,
},
{
name: 'meta2',
@ -131,6 +139,7 @@ export default function ({ getService }) {
aggregatable: false,
searchable: false,
readFromDocValues: false,
metadata_field: true,
},
],
});

View file

@ -35,6 +35,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
{
name: 'number_conflict',
@ -43,6 +44,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: true,
metadata_field: false,
},
{
name: 'string_conflict',
@ -51,6 +53,7 @@ export default function ({ getService }) {
aggregatable: true,
searchable: true,
readFromDocValues: false,
metadata_field: false,
},
{
name: 'success',
@ -63,6 +66,7 @@ export default function ({ getService }) {
boolean: ['logs-2017.01.02'],
keyword: ['logs-2017.01.01'],
},
metadata_field: false,
},
],
});

View file

@ -25,6 +25,7 @@ export default function ({ getService }) {
aggregatable: true,
name: 'bar',
readFromDocValues: true,
metadata_field: false,
},
{
type: 'string',
@ -33,6 +34,7 @@ export default function ({ getService }) {
aggregatable: false,
name: 'baz',
readFromDocValues: false,
metadata_field: false,
},
{
type: 'string',
@ -42,6 +44,7 @@ export default function ({ getService }) {
name: 'baz.keyword',
readFromDocValues: true,
subType: { multi: { parent: 'baz' } },
metadata_field: false,
},
{
type: 'number',
@ -50,6 +53,7 @@ export default function ({ getService }) {
aggregatable: true,
name: 'foo',
readFromDocValues: true,
metadata_field: false,
},
{
aggregatable: true,
@ -63,6 +67,7 @@ export default function ({ getService }) {
},
},
type: 'string',
metadata_field: false,
},
];
@ -100,6 +105,7 @@ export default function ({ getService }) {
readFromDocValues: false,
searchable: true,
type: 'string',
metadata_field: true,
},
{
aggregatable: false,
@ -108,6 +114,7 @@ export default function ({ getService }) {
readFromDocValues: false,
searchable: false,
type: '_source',
metadata_field: true,
},
{
type: 'boolean',
@ -116,6 +123,7 @@ export default function ({ getService }) {
aggregatable: true,
name: 'bar',
readFromDocValues: true,
metadata_field: false,
},
{
aggregatable: false,
@ -124,6 +132,7 @@ export default function ({ getService }) {
readFromDocValues: false,
searchable: true,
type: 'string',
metadata_field: false,
},
{
type: 'string',
@ -133,6 +142,7 @@ export default function ({ getService }) {
name: 'baz.keyword',
readFromDocValues: true,
subType: { multi: { parent: 'baz' } },
metadata_field: false,
},
{
aggregatable: false,
@ -140,6 +150,7 @@ export default function ({ getService }) {
readFromDocValues: false,
searchable: false,
type: 'string',
metadata_field: true,
},
{
type: 'number',
@ -148,6 +159,7 @@ export default function ({ getService }) {
aggregatable: true,
name: 'foo',
readFromDocValues: true,
metadata_field: false,
},
{
aggregatable: true,
@ -161,6 +173,7 @@ export default function ({ getService }) {
},
},
type: 'string',
metadata_field: false,
},
],
})