Skip to content

Commit

Permalink
[Search] [Onboarding] Update example data for index (#201983)
Browse files Browse the repository at this point in the history
Improve generated vector db data in the index
Use: 
- Ironman
- Batman
- Black Widow


<img width="1178" alt="image"
src="https://github.com/user-attachments/assets/c47bada6-551e-4eef-9409-3041c2f7f9dd">
<img width="1178" alt="image"
src="https://github.com/user-attachments/assets/112b558d-5fa1-4c61-a40d-993e344d3a9c">

---------

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
yansavitski and elasticmachine authored Dec 4, 2024
1 parent 52f25c2 commit 140f80d
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { render } from '@testing-library/react';
import {
AddDocumentsCodeExample,
basicExampleTexts,
exampleTextsWithCustomMapping,
} from './add_documents_code_example';
import { generateSampleDocument } from '../../utils/document_generation';
import { MappingProperty } from '@elastic/elasticsearch/lib/api/types';

jest.mock('../../utils/language', () => ({
getDefaultCodingLanguage: jest.fn().mockReturnValue('python'),
}));

jest.mock('../../hooks/use_asset_base_path', () => ({
useAssetBasePath: jest.fn().mockReturnValue('/plugins/'),
}));

jest.mock('../../utils/document_generation', () => ({
generateSampleDocument: jest.fn(),
}));

jest.mock('../../hooks/use_elasticsearch_url', () => ({
useElasticsearchUrl: jest.fn(),
}));

jest.mock('@kbn/search-api-keys-components', () => ({
useSearchApiKey: jest.fn().mockReturnValue({ apiKey: 'test-api-key' }),
}));

jest.mock('../../hooks/use_kibana', () => ({
useKibana: jest.fn().mockReturnValue({
services: {
application: {},
share: {},
console: {},
},
}),
}));

jest.mock('../../contexts/usage_tracker_context', () => ({
useUsageTracker: jest.fn().mockReturnValue({
count: jest.fn(),
click: jest.fn(),
}),
}));

describe('AddDocumentsCodeExample', () => {
afterEach(() => {
jest.clearAllMocks();
});

describe('generateSampleDocument', () => {
it('pass basic examples when mapping is default', () => {
const indexName = 'test-index';
const mappingProperties: Record<string, MappingProperty> = {
vector: { type: 'dense_vector', dims: 3 },
text: { type: 'text' },
};

render(
<AddDocumentsCodeExample indexName={indexName} mappingProperties={mappingProperties} />
);

expect(generateSampleDocument).toHaveBeenCalledTimes(3);

basicExampleTexts.forEach((text, index) => {
expect(generateSampleDocument).toHaveBeenNthCalledWith(index + 1, mappingProperties, text);
});
});

it('pass basic examples when mapping is not passed', () => {
const indexName = 'test-index';

render(<AddDocumentsCodeExample indexName={indexName} mappingProperties={{}} />);

expect(generateSampleDocument).toHaveBeenCalledTimes(3);

const mappingProperties: Record<string, MappingProperty> = {
vector: { type: 'dense_vector', dims: 3 },
text: { type: 'text' },
};

basicExampleTexts.forEach((text, index) => {
expect(generateSampleDocument).toHaveBeenNthCalledWith(index + 1, mappingProperties, text);
});
});

it('pass basic examples when mapping is default with extra vector fields', () => {
const indexName = 'test-index';
const mappingProperties: Record<string, MappingProperty> = {
vector: { type: 'dense_vector', dims: 3, similarity: 'extra' },
text: { type: 'text' },
};

render(
<AddDocumentsCodeExample indexName={indexName} mappingProperties={mappingProperties} />
);

expect(generateSampleDocument).toHaveBeenCalledTimes(3);

basicExampleTexts.forEach((text, index) => {
expect(generateSampleDocument).toHaveBeenNthCalledWith(index + 1, mappingProperties, text);
});
});

it('pass examples text when mapping is custom', () => {
const indexName = 'test-index';
const mappingProperties: Record<string, MappingProperty> = {
text: { type: 'text' },
test: { type: 'boolean' },
};

render(
<AddDocumentsCodeExample indexName={indexName} mappingProperties={mappingProperties} />
);

expect(generateSampleDocument).toHaveBeenCalledTimes(3);

exampleTextsWithCustomMapping.forEach((text, index) => {
expect(generateSampleDocument).toHaveBeenNthCalledWith(index + 1, mappingProperties, text);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
*/

import React, { useCallback, useMemo, useState } from 'react';
import { MappingProperty } from '@elastic/elasticsearch/lib/api/types';
import { MappingDenseVectorProperty, MappingProperty } from '@elastic/elasticsearch/lib/api/types';
import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { TryInConsoleButton } from '@kbn/try-in-console';
import { isEqual } from 'lodash';

import { useSearchApiKey } from '@kbn/search-api-keys-components';
import { useKibana } from '../../hooks/use_kibana';
Expand All @@ -24,6 +25,13 @@ import { CodeSample } from '../shared/code_sample';
import { generateSampleDocument } from '../../utils/document_generation';
import { getDefaultCodingLanguage } from '../../utils/language';

export const basicExampleTexts = [
'Yellowstone National Park',
'Yosemite National Park',
'Rocky Mountain National Park',
];
export const exampleTextsWithCustomMapping = [1, 2, 3].map((num) => `Example text ${num}`);

export interface AddDocumentsCodeExampleProps {
indexName: string;
mappingProperties: Record<string, MappingProperty>;
Expand Down Expand Up @@ -56,10 +64,19 @@ export const AddDocumentsCodeExample = ({
[usageTracker]
);
const sampleDocuments = useMemo(() => {
return [1, 2, 3].map((num) =>
generateSampleDocument(codeSampleMappings, `Example text ${num}`)
);
}, [codeSampleMappings]);
// If the default mapping was used, we need to exclude generated vector fields
const copyCodeSampleMappings = {
...codeSampleMappings,
vector: {
type: codeSampleMappings.vector?.type,
dims: (codeSampleMappings.vector as MappingDenseVectorProperty)?.dims,
},
};
const isDefaultMapping = isEqual(copyCodeSampleMappings, ingestCodeExamples.defaultMapping);
const sampleTexts = isDefaultMapping ? basicExampleTexts : exampleTextsWithCustomMapping;

return sampleTexts.map((text) => generateSampleDocument(codeSampleMappings, text));
}, [codeSampleMappings, ingestCodeExamples.defaultMapping]);
const { apiKey } = useSearchApiKey();
const codeParams: IngestCodeSnippetParameters = useMemo(() => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,33 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont
);
},

async expectHasSampleDocuments() {
await testSubjects.existOrFail('ingestDataCodeExample-code-block');
expect(await testSubjects.getVisibleText('ingestDataCodeExample-code-block')).to.contain(
'Yellowstone National Park'
);
expect(await testSubjects.getVisibleText('ingestDataCodeExample-code-block')).to.contain(
'Yosemite National Park'
);
expect(await testSubjects.getVisibleText('ingestDataCodeExample-code-block')).to.contain(
'Rocky Mountain National Park'
);
},

async expectSampleDocumentsWithCustomMappings() {
await browser.refresh();
await testSubjects.existOrFail('ingestDataCodeExample-code-block');
expect(await testSubjects.getVisibleText('ingestDataCodeExample-code-block')).to.contain(
'Example text 1'
);
expect(await testSubjects.getVisibleText('ingestDataCodeExample-code-block')).to.contain(
'Example text 2'
);
expect(await testSubjects.getVisibleText('ingestDataCodeExample-code-block')).to.contain(
'Example text 3'
);
},

async clickFirstDocumentDeleteAction() {
await testSubjects.existOrFail('documentMetadataButton');
await testSubjects.click('documentMetadataButton');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,33 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await pageObjects.svlSearchIndexDetailPage.expectConnectionDetails();
});

describe('check code example texts', () => {
const indexNameCodeExample = 'test-my-index2';
before(async () => {
await es.indices.create({ index: indexNameCodeExample });
await svlSearchNavigation.navigateToIndexDetailPage(indexNameCodeExample);
});

after(async () => {
await esDeleteAllIndices(indexNameCodeExample);
});

it('should have basic example texts', async () => {
await pageObjects.svlSearchIndexDetailPage.expectHasSampleDocuments();
});

it('should have other example texts when mapping changed', async () => {
await es.indices.putMapping({
index: indexNameCodeExample,
properties: {
text: { type: 'text' },
number: { type: 'integer' },
},
});
await pageObjects.svlSearchIndexDetailPage.expectSampleDocumentsWithCustomMappings();
});
});

describe.skip('API key details', () => {
// Flaky test related with deleting API keys
it('should show api key', async () => {
Expand Down

0 comments on commit 140f80d

Please sign in to comment.