|
| 1 | +[[bring-your-own-vectors]] |
| 2 | +=== Bring your own dense vector embeddings to {es} |
| 3 | +++++ |
| 4 | +<titleabbrev>Bring your own dense vectors</titleabbrev> |
| 5 | +++++ |
| 6 | + |
| 7 | +This tutorial demonstrates how to index documents that already have dense vector embeddings into {es}. |
| 8 | +You'll also learn the syntax for searching these documents using a `knn` query. |
| 9 | + |
| 10 | +You'll find links at the end of this tutorial for more information about deploying a text embedding model in {es}, so you can generate embeddings for queries on the fly. |
| 11 | + |
| 12 | +[TIP] |
| 13 | +==== |
| 14 | +This is an advanced use case. |
| 15 | +Refer to <<semantic-search,Semantic search>> for an overview of your options for semantic search with {es}. |
| 16 | +==== |
| 17 | + |
| 18 | +[discrete] |
| 19 | +[[bring-your-own-vectors-create-index]] |
| 20 | +=== Step 1: Create an index with `dense_vector` mapping |
| 21 | + |
| 22 | +Each document in our simple dataset will have: |
| 23 | + |
| 24 | +* A review: stored in a `review_text` field |
| 25 | +* An embedding of that review: stored in a `review_vector` field |
| 26 | +** The `review_vector` field is defined as a <<dense-vector,`dense_vector`>> data type. |
| 27 | + |
| 28 | +[TIP] |
| 29 | +==== |
| 30 | +The `dense_vector` type automatically uses `int8_hnsw` quantization by default to reduce the memory footprint required when searching float vectors. |
| 31 | +Learn more about balancing performance and accuracy in <<dense-vector-quantization,Dense vector quantization>>. |
| 32 | +==== |
| 33 | + |
| 34 | +[source,console] |
| 35 | +---- |
| 36 | +PUT /amazon-reviews |
| 37 | +{ |
| 38 | + "mappings": { |
| 39 | + "properties": { |
| 40 | + "review_vector": { |
| 41 | + "type": "dense_vector", |
| 42 | + "dims": 8, <1> |
| 43 | + "index": true, <2> |
| 44 | + "similarity": "cosine" <3> |
| 45 | + }, |
| 46 | + "review_text": { |
| 47 | + "type": "text" |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | +} |
| 52 | +---- |
| 53 | +// TEST SETUP |
| 54 | +<1> The `dims` parameter must match the length of the embedding vector. Here we're using a simple 8-dimensional embedding for readability. If not specified, `dims` will be dynamically calculated based on the first indexed document. |
| 55 | +<2> The `index` parameter is set to `true` to enable the use of the `knn` query. |
| 56 | +<3> The `similarity` parameter defines the similarity function used to compare the query vector to the document vectors. `cosine` is the default similarity function for `dense_vector` fields in {es}. |
| 57 | + |
| 58 | +[discrete] |
| 59 | +[[bring-your-own-vectors-index-documents]] |
| 60 | +=== Step 2: Index documents with embeddings |
| 61 | + |
| 62 | +[discrete] |
| 63 | +==== Index a single document |
| 64 | + |
| 65 | +First, index a single document to understand the document structure. |
| 66 | + |
| 67 | +[source,console] |
| 68 | +---- |
| 69 | +PUT /amazon-reviews/_doc/1 |
| 70 | +{ |
| 71 | + "review_text": "This product is lifechanging! I'm telling all my friends about it.", |
| 72 | + "review_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8] <1> |
| 73 | +} |
| 74 | +---- |
| 75 | +// TEST |
| 76 | +<1> The size of the `review_vector` array is 8, matching the `dims` count specified in the mapping. |
| 77 | + |
| 78 | +[discrete] |
| 79 | +==== Bulk index multiple documents |
| 80 | + |
| 81 | +In a production scenario, you'll want to index many documents at once using the <<docs-bulk,`_bulk` endpoint>>. |
| 82 | + |
| 83 | +Here's an example of indexing multiple documents in a single `_bulk` request. |
| 84 | + |
| 85 | +[source,console] |
| 86 | +---- |
| 87 | +POST /_bulk |
| 88 | +{ "index": { "_index": "amazon-reviews", "_id": "2" } } |
| 89 | +{ "review_text": "This product is amazing! I love it.", "review_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8] } |
| 90 | +{ "index": { "_index": "amazon-reviews", "_id": "3" } } |
| 91 | +{ "review_text": "This product is terrible. I hate it.", "review_vector": [0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1] } |
| 92 | +{ "index": { "_index": "amazon-reviews", "_id": "4" } } |
| 93 | +{ "review_text": "This product is great. I can do anything with it.", "review_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8] } |
| 94 | +{ "index": { "_index": "amazon-reviews", "_id": "5" } } |
| 95 | +{ "review_text": "This product has ruined my life and the lives of my family and friends.", "review_vector": [0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1] } |
| 96 | +---- |
| 97 | +// TEST[continued] |
| 98 | + |
| 99 | +[discrete] |
| 100 | +[[bring-your-own-vectors-search-documents]] |
| 101 | +=== Step 3: Search documents with embeddings |
| 102 | + |
| 103 | +Now you can query these document vectors using a <<knn-retriever,`knn` retriever>>. |
| 104 | +`knn` is a type of vector search, which finds the `k` most similar documents to a query vector. |
| 105 | +Here we're simply using a raw vector for the query text, for demonstration purposes. |
| 106 | + |
| 107 | +[source,console] |
| 108 | +---- |
| 109 | +POST /amazon-reviews/_search |
| 110 | +{ |
| 111 | + "retriever": { |
| 112 | + "knn": { |
| 113 | + "field": "review_vector", |
| 114 | + "query_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8], <1> |
| 115 | + "k": 2, <2> |
| 116 | + "num_candidates": 5 <3> |
| 117 | + } |
| 118 | + } |
| 119 | +} |
| 120 | +---- |
| 121 | +// TEST[skip:flakeyknnerror] |
| 122 | +<1> In this simple example, we're sending a raw vector as the query text. In a real-world scenario, you'll need to generate vectors for queries using an embedding model. |
| 123 | +<2> The `k` parameter specifies the number of results to return. |
| 124 | +<3> The `num_candidates` parameter is optional. It limits the number of candidates returned by the search node. This can improve performance and reduce costs. |
| 125 | + |
| 126 | +[discrete] |
| 127 | +[[bring-your-own-vectors-learn-more]] |
| 128 | +=== Learn more |
| 129 | + |
| 130 | +In this simple example, we're sending a raw vector for the query text. |
| 131 | +In a real-world scenario you won't know the query text ahead of time. |
| 132 | +You'll need to generate query vectors, on the fly, using the same embedding model that generated the document vectors. |
| 133 | + |
| 134 | +For this you'll need to deploy a text embedding model in {es} and use the <<knn-query-top-level-parameters,`query_vector_builder` parameter>>. Alternatively, you can generate vectors client-side and send them directly with the search request. |
| 135 | + |
| 136 | +Learn how to <<semantic-search-deployed-nlp-model,use a deployed text embedding model>> for semantic search. |
| 137 | + |
| 138 | +[TIP] |
| 139 | +==== |
| 140 | +If you're just getting started with vector search in {es}, refer to <<semantic-search,Semantic search>>. |
| 141 | +==== |
0 commit comments