Skip to content

Commit

Permalink
[Discover][Surrounding Documents] Fix time range filter
Browse files Browse the repository at this point in the history
  • Loading branch information
jughosta committed Jun 26, 2024
1 parent 650983a commit abd583c
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 161 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ export function createSearchSourceStub(hits: EsHitRecord[], timeField?: string)
const searchSourceStub: any = {
_stubHits: hits,
_stubTimeField: timeField,
_createStubHit: (timestamp: number, tiebreaker = 0) => ({
[searchSourceStub._stubTimeField]: timestamp,
sort: [timestamp, tiebreaker],
}),
_createStubHit: (timestamp: number, tiebreaker = 0) => {
const value = moment(timestamp).toISOString();
return {
[searchSourceStub._stubTimeField]: value,
sort: [value, tiebreaker],
};
},
setParent: sinon.spy(() => searchSourceStub),
setField: sinon.spy(() => searchSourceStub),
removeField: sinon.spy(() => searchSourceStub),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ describe('context predecessors', function () {
let dataPluginMock: DataPublicPluginStart;
let fetchPredecessors: (
timeValIso: string,
timeValNr: number,
tieBreakerField: string,
tieBreakerValue: number,
size: number
Expand Down Expand Up @@ -63,14 +62,14 @@ describe('context predecessors', function () {
},
} as unknown as DataPublicPluginStart;

fetchPredecessors = (timeValIso, timeValNr, tieBreakerField, tieBreakerValue, size = 10) => {
fetchPredecessors = (timeValIso, tieBreakerField, tieBreakerValue, size = 10) => {
const anchor = buildDataTableRecord(
{
_id: 'test',
_source: {
[dataView.timeFieldName!]: timeValIso,
},
sort: [timeValNr, tieBreakerValue],
sort: [timeValIso, tieBreakerValue],
} as EsHitRecord,
dataView,
true
Expand Down Expand Up @@ -100,17 +99,15 @@ describe('context predecessors', function () {
mockSearchSource._createStubHit(MS_PER_DAY * 1000),
];

return fetchPredecessors(ANCHOR_TIMESTAMP_3000, MS_PER_DAY * 3000, '_doc', 0, 3).then(
({ rows }) => {
expect(mockSearchSource.fetch$.calledOnce).toBe(true);
expect(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(0, 3),
dataView,
})
);
}
);
return fetchPredecessors(ANCHOR_TIMESTAMP_3000, '_doc', 0, 3).then(({ rows }) => {
expect(mockSearchSource.fetch$.calledOnce).toBe(true);
expect(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(0, 3),
dataView,
})
);
});
});

it('should perform multiple queries with the last being unrestricted when too few hits are returned', function () {
Expand All @@ -122,30 +119,28 @@ describe('context predecessors', function () {
mockSearchSource._createStubHit(MS_PER_DAY * 2990),
];

return fetchPredecessors(ANCHOR_TIMESTAMP_3000, MS_PER_DAY * 3000, '_doc', 0, 6).then(
({ rows }) => {
const intervals: Timestamp[] = mockSearchSource.setField.args
.filter(([property]: string) => property === 'query')
.map(([, { query }]: [string, { query: Query }]) =>
get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp'])
);

expect(
intervals.every(({ gte, lte }) => (gte && lte ? moment(gte).isBefore(lte) : true))
).toBe(true);
// should have started at the given time
expect(intervals[0].gte).toEqual(moment(MS_PER_DAY * 3000).toISOString());
// should have ended with a half-open interval
expect(Object.keys(last(intervals) ?? {})).toEqual(['format', 'gte']);
expect(intervals.length).toBeGreaterThan(1);
expect(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(0, 3),
dataView,
})
return fetchPredecessors(ANCHOR_TIMESTAMP_3000, '_doc', 0, 6).then(({ rows }) => {
const intervals: Timestamp[] = mockSearchSource.setField.args
.filter(([property]: string) => property === 'query')
.map(([, { query }]: [string, { query: Query }]) =>
get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp'])
);
}
);

expect(
intervals.every(({ gte, lte }) => (gte && lte ? moment(gte).isBefore(lte) : true))
).toBe(true);
// should have started at the given time
expect(intervals[0].gte).toEqual(moment(MS_PER_DAY * 3000).toISOString());
// should have ended with a half-open interval
expect(Object.keys(last(intervals) ?? {})).toEqual(['format', 'gte']);
expect(intervals.length).toBeGreaterThan(1);
expect(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(0, 3),
dataView,
})
);
});
});

it('should perform multiple queries until the expected hit count is returned', function () {
Expand All @@ -156,55 +151,45 @@ describe('context predecessors', function () {
mockSearchSource._createStubHit(MS_PER_DAY * 1000),
];

return fetchPredecessors(ANCHOR_TIMESTAMP_1000, MS_PER_DAY * 1000, '_doc', 0, 3).then(
({ rows }) => {
const intervals: Timestamp[] = mockSearchSource.setField.args
.filter(([property]: string) => property === 'query')
.map(([, { query }]: [string, { query: Query }]) => {
return get(query, [
'bool',
'must',
'constant_score',
'filter',
'range',
'@timestamp',
]);
});
return fetchPredecessors(ANCHOR_TIMESTAMP_1000, '_doc', 0, 3).then(({ rows }) => {
const intervals: Timestamp[] = mockSearchSource.setField.args
.filter(([property]: string) => property === 'query')
.map(([, { query }]: [string, { query: Query }]) => {
return get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp']);
});

// should have started at the given time
expect(intervals[0].gte).toEqual(moment(MS_PER_DAY * 1000).toISOString());
// should have stopped before reaching MS_PER_DAY * 1700
expect(moment(last(intervals)?.lte).valueOf()).toBeLessThan(MS_PER_DAY * 1700);
expect(intervals.length).toBeGreaterThan(1);
expect(intervals).toMatchSnapshot();
// should have started at the given time
expect(intervals[0].gte).toEqual(moment(MS_PER_DAY * 1000).toISOString());
// should have stopped before reaching MS_PER_DAY * 1700
expect(moment(last(intervals)?.lte).valueOf()).toBeLessThan(MS_PER_DAY * 1700);
expect(intervals.length).toBeGreaterThan(1);

expect(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(-3),
dataView,
})
);
}
);
expect(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(-3),
dataView,
})
);
});
});

it('should return an empty array when no hits were found', function () {
return fetchPredecessors(ANCHOR_TIMESTAMP_3, MS_PER_DAY * 3, '_doc', 0, 3).then(
({ rows }) => {
expect(rows).toEqual([]);
}
);
return fetchPredecessors(ANCHOR_TIMESTAMP_3, '_doc', 0, 3).then(({ rows }) => {
expect(rows).toEqual([]);
});
});

it('should configure the SearchSource to not inherit from the implicit root', function () {
return fetchPredecessors(ANCHOR_TIMESTAMP_3, MS_PER_DAY * 3, '_doc', 0, 3).then(() => {
return fetchPredecessors(ANCHOR_TIMESTAMP_3, '_doc', 0, 3).then(() => {
const setParentSpy = mockSearchSource.setParent;
expect(setParentSpy.alwaysCalledWith(undefined)).toBe(true);
expect(setParentSpy.called).toBe(true);
});
});

it('should set the tiebreaker sort order to the opposite as the time field', function () {
return fetchPredecessors(ANCHOR_TIMESTAMP, MS_PER_DAY, '_doc', 0, 3).then(() => {
return fetchPredecessors(ANCHOR_TIMESTAMP, '_doc', 0, 3).then(() => {
expect(
mockSearchSource.setField.calledWith('sort', [
{ '@timestamp': { order: 'asc', format: 'strict_date_optional_time' } },
Expand All @@ -227,14 +212,14 @@ describe('context predecessors', function () {
},
} as unknown as DataPublicPluginStart;

fetchPredecessors = (timeValIso, timeValNr, tieBreakerField, tieBreakerValue, size = 10) => {
fetchPredecessors = (timeValIso, tieBreakerField, tieBreakerValue, size = 10) => {
const anchor = buildDataTableRecord(
{
_id: 'test',
_source: {
[dataView.timeFieldName!]: timeValIso,
},
sort: [timeValNr, tieBreakerValue],
sort: [timeValIso, tieBreakerValue],
} as EsHitRecord,
dataView,
true
Expand Down Expand Up @@ -264,21 +249,19 @@ describe('context predecessors', function () {
mockSearchSource._createStubHit(MS_PER_DAY * 1000),
];

return fetchPredecessors(ANCHOR_TIMESTAMP_3000, MS_PER_DAY * 3000, '_doc', 0, 3).then(
({ rows }) => {
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(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(0, 3),
dataView,
})
);
}
);
return fetchPredecessors(ANCHOR_TIMESTAMP_3000, '_doc', 0, 3).then(({ rows }) => {
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(rows).toEqual(
buildDataTableRecordList({
records: mockSearchSource._stubHits.slice(0, 3),
dataView,
})
);
});
});
});
});
Loading

0 comments on commit abd583c

Please sign in to comment.