From eed015daebca691df93c9859ec50db12d6aaaf96 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Fri, 18 Oct 2024 16:00:36 -0500 Subject: [PATCH] [Search][Onboarding] improve sample documents (#196772) ## Summary Updating the onboarding ingest code snippet to display 3 document instead of 1. Updated the Run in Console CTA to always show. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --- .../public/code_examples/curl.ts | 21 +++++----- .../public/code_examples/javascript.ts | 6 +-- .../public/code_examples/python.ts | 6 +-- .../public/code_examples/sense.ts | 13 ++++-- .../add_documents_code_example.tsx | 41 +++++++++---------- .../components/start/create_index_code.tsx | 32 +++++++-------- x-pack/plugins/search_indices/public/types.ts | 2 +- .../public/utils/document_generation.test.ts | 20 +++++++-- .../public/utils/document_generation.ts | 11 ++--- 9 files changed, 83 insertions(+), 69 deletions(-) diff --git a/x-pack/plugins/search_indices/public/code_examples/curl.ts b/x-pack/plugins/search_indices/public/code_examples/curl.ts index a451f7cf089671..a73d5a7cfe617b 100644 --- a/x-pack/plugins/search_indices/public/code_examples/curl.ts +++ b/x-pack/plugins/search_indices/public/code_examples/curl.ts @@ -48,18 +48,19 @@ export const CurlCreateIndexExamples: CreateIndexLanguageExamples = { }; export const CurlVectorsIngestDataExample: IngestDataCodeDefinition = { - ingestCommand: ({ - elasticsearchURL, - apiKey, - indexName, - sampleDocument, - }) => `curl -X POST "${elasticsearchURL}/_bulk?pretty" \ + ingestCommand: ({ elasticsearchURL, apiKey, indexName, sampleDocuments }) => { + let result = `curl -X POST "${elasticsearchURL}/_bulk?pretty" \ --header 'Authorization: ApiKey ${apiKey ?? API_KEY_PLACEHOLDER}' \ --header 'Content-Type: application/json' \ --d' -{ "index": { "_index": "${indexName}" } } -${JSON.stringify(sampleDocument)} -`, +-d'`; + sampleDocuments.forEach((document) => { + result += ` +{ "index" : { "_index" : "${indexName}" } } +${JSON.stringify(document)}`; + }); + result += "\n'"; + return result; + }, updateMappingsCommand: ({ elasticsearchURL, apiKey, diff --git a/x-pack/plugins/search_indices/public/code_examples/javascript.ts b/x-pack/plugins/search_indices/public/code_examples/javascript.ts index a819b973388f40..75de93e485742d 100644 --- a/x-pack/plugins/search_indices/public/code_examples/javascript.ts +++ b/x-pack/plugins/search_indices/public/code_examples/javascript.ts @@ -73,7 +73,7 @@ export const JSServerlessIngestVectorDataExample: IngestDataCodeDefinition = { ingestCommand: ({ apiKey, elasticsearchURL, - sampleDocument, + sampleDocuments, indexName, }) => `import { Client } from "@elastic/elasticsearch"; @@ -85,9 +85,7 @@ const client = new Client({ }); const index = "${indexName}"; -const docs = [ -${JSON.stringify(sampleDocument, null, 2)}, -] +const docs = ${JSON.stringify(sampleDocuments, null, 2)}; const bulkIngestResponse = await client.helpers.bulk({ index, diff --git a/x-pack/plugins/search_indices/public/code_examples/python.ts b/x-pack/plugins/search_indices/public/code_examples/python.ts index ac405cfecd1e9d..cf2b06603c381d 100644 --- a/x-pack/plugins/search_indices/public/code_examples/python.ts +++ b/x-pack/plugins/search_indices/public/code_examples/python.ts @@ -71,7 +71,7 @@ const serverlessIngestionCommand: IngestCodeSnippetFunction = ({ elasticsearchURL, apiKey, indexName, - sampleDocument, + sampleDocuments, }) => `from elasticsearch import Elasticsearch, helpers client = Elasticsearch( @@ -81,9 +81,7 @@ client = Elasticsearch( index_name = "${indexName}" -docs = [ -${JSON.stringify(sampleDocument, null, 4)}, -] +docs = ${JSON.stringify(sampleDocuments, null, 4)} bulk_response = helpers.bulk(client, docs, index=index_name) print(bulk_response)`; diff --git a/x-pack/plugins/search_indices/public/code_examples/sense.ts b/x-pack/plugins/search_indices/public/code_examples/sense.ts index c1864287ab1695..34e4e81802762d 100644 --- a/x-pack/plugins/search_indices/public/code_examples/sense.ts +++ b/x-pack/plugins/search_indices/public/code_examples/sense.ts @@ -32,10 +32,15 @@ export const ConsoleCreateIndexExamples: CreateIndexLanguageExamples = { }; export const ConsoleVectorsIngestDataExample: IngestDataCodeDefinition = { - ingestCommand: ({ indexName, sampleDocument }) => `POST /_bulk?pretty -{ "index": { "_index": "${indexName}" } } -${JSON.stringify(sampleDocument)} -`, + ingestCommand: ({ indexName, sampleDocuments }) => { + let result = 'POST /_bulk?pretty\n'; + sampleDocuments.forEach((document) => { + result += `{ "index": { "_index": "${indexName}" } } +${JSON.stringify(document)}`; + }); + result += '\n'; + return result; + }, updateMappingsCommand: ({ indexName, mappingProperties }) => `PUT /${indexName}/_mapping ${JSON.stringify({ properties: mappingProperties }, null, 2)}`, }; diff --git a/x-pack/plugins/search_indices/public/components/index_documents/add_documents_code_example.tsx b/x-pack/plugins/search_indices/public/components/index_documents/add_documents_code_example.tsx index 20d7fa534e6747..cdd773f4e6a812 100644 --- a/x-pack/plugins/search_indices/public/components/index_documents/add_documents_code_example.tsx +++ b/x-pack/plugins/search_indices/public/components/index_documents/add_documents_code_example.tsx @@ -55,16 +55,17 @@ export const AddDocumentsCodeExample = ({ }, [usageTracker] ); - const sampleDocument = useMemo(() => { - // TODO: implement smart document generation - return generateSampleDocument(codeSampleMappings); + const sampleDocuments = useMemo(() => { + return [1, 2, 3].map((num) => + generateSampleDocument(codeSampleMappings, `Example text ${num}`) + ); }, [codeSampleMappings]); const { apiKey, apiKeyIsVisible } = useSearchApiKey(); const codeParams: IngestCodeSnippetParameters = useMemo(() => { return { indexName, elasticsearchURL: elasticsearchUrl, - sampleDocument, + sampleDocuments, indexHasMappings, mappingProperties: codeSampleMappings, apiKey: apiKeyIsVisible && apiKey ? apiKey : undefined, @@ -72,7 +73,7 @@ export const AddDocumentsCodeExample = ({ }, [ indexName, elasticsearchUrl, - sampleDocument, + sampleDocuments, codeSampleMappings, indexHasMappings, apiKeyIsVisible, @@ -95,22 +96,20 @@ export const AddDocumentsCodeExample = ({ onSelectLanguage={onSelectLanguage} /> - {selectedLanguage === 'curl' && ( - - - - )} + + + {selectedCodeExamples.installCommand && ( diff --git a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx index eda63a5f95594a..fadfe1c7dcb90f 100644 --- a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx +++ b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx @@ -78,23 +78,21 @@ export const CreateIndexCodeView = ({ onSelectLanguage={onSelectLanguage} /> - {selectedLanguage === 'curl' && ( - - { - usageTracker.click([ - AnalyticsEvents.startCreateIndexRunInConsole, - `${AnalyticsEvents.startCreateIndexRunInConsole}_${selectedLanguage}`, - ]); - }} - /> - - )} + + { + usageTracker.click([ + AnalyticsEvents.startCreateIndexRunInConsole, + `${AnalyticsEvents.startCreateIndexRunInConsole}_${selectedLanguage}`, + ]); + }} + /> + {selectedCodeExample.installCommand && ( ; } diff --git a/x-pack/plugins/search_indices/public/utils/document_generation.test.ts b/x-pack/plugins/search_indices/public/utils/document_generation.test.ts index 67ae2e81f3c144..9f0767fbb09f31 100644 --- a/x-pack/plugins/search_indices/public/utils/document_generation.test.ts +++ b/x-pack/plugins/search_indices/public/utils/document_generation.test.ts @@ -22,7 +22,21 @@ describe('document generation util', () => { expect(result).toEqual({ title: 'Sample text for title', tags: 'sample-keyword-tags', - body: 'Hello World', + body: 'Sample text for body', + }); + }); + + it('should support providing sample text', () => { + const mapping: Record = { + body: { type: 'semantic_text', inference_id: '.elser_model_2' }, + title: { type: 'text' }, + }; + + const result = generateSampleDocument(mapping, 'Testing sample text!'); + + expect(result).toEqual({ + title: 'Testing sample text!', + body: 'Testing sample text!', }); }); @@ -113,8 +127,8 @@ describe('document generation util', () => { const result = generateSampleDocument(mapping); expect(Array.isArray(result.embedding)).toBe(true); - expect((result.embedding as number[]).length!).toBe(21); - expect((result.embedding as number[])[20]).toBe('...'); + expect((result.embedding as number[]).length!).toBe(11); + expect((result.embedding as number[])[10]).toBe('...'); }); it('should generate a sample document for sparse_vector fields', () => { diff --git a/x-pack/plugins/search_indices/public/utils/document_generation.ts b/x-pack/plugins/search_indices/public/utils/document_generation.ts index 42f4dc88ee5b26..95706e8313d31e 100644 --- a/x-pack/plugins/search_indices/public/utils/document_generation.ts +++ b/x-pack/plugins/search_indices/public/utils/document_generation.ts @@ -11,7 +11,8 @@ import type { } from '@elastic/elasticsearch/lib/api/types'; export function generateSampleDocument( - mappingProperties: Record + mappingProperties: Record, + sampleText?: string ): Record { const sampleDocument: Record = {}; @@ -19,13 +20,13 @@ export function generateSampleDocument( if ('type' in mapping) { switch (mapping.type) { case 'text': - sampleDocument[field] = `Sample text for ${field}`; + sampleDocument[field] = sampleText ?? `Sample text for ${field}`; break; case 'keyword': sampleDocument[field] = `sample-keyword-${field}`; break; case 'semantic_text': - sampleDocument[field] = 'Hello World'; + sampleDocument[field] = sampleText ?? `Sample text for ${field}`; break; case 'integer': case 'long': @@ -74,9 +75,9 @@ export function generateSampleDocument( return sampleDocument; } -function generateDenseVector(mapping: MappingDenseVectorProperty, maxDisplayDims = 20) { +function generateDenseVector(mapping: MappingDenseVectorProperty, maxDisplayDims = 10) { // Limit the dimensions for better UI display - const dimension = Math.min(mapping?.dims ?? 20, maxDisplayDims); + const dimension = Math.min(mapping?.dims ?? 10, maxDisplayDims); // Generate an array of random floating-point numbers const denseVector: Array = Array.from({ length: dimension }, () =>