Link Search Menu Expand Document Documentation Menu

Template queries

Introduced 2.19

A template query allows you to create queries with dynamic placeholders that are resolved by search request processors during query execution. This is particularly useful when your query parameters need to be generated or transformed during the search process, such as when using machine learning (ML) inference to convert text into vector embeddings.

The following search implementations benefit from using template queries:

  • Converting text input into vector embeddings for vector search
  • Dynamic query parameter generation based on runtime calculations
  • Complex query transformations that require intermediate processing

Placeholders are defined using the "${variable_name}" syntax (note that the variables must be enclosed in quotation marks). Search request processors can generate or transform data to fill these placeholders before the query is processed. The template query acts as a container for the final executable query.

Example

The following example demonstrates using a template query with an ml_inference search request processor for semantic search.

Prerequisite

Before using an ml_inference search request processor, you must configure an ML model. For more information about local models, see Using ML models within OpenSearch. For more information about externally hosted models, see Connecting to externally hosted models.

Once you configure a model, you can test the model by sending a Predict API request:

POST /_plugins/_ml/models/mBGzipQB2gmRjlv_dOoB/_predict
{
  "parameters": {
    "inputText": "happy moments"
  }
}

The response contains an embedding field with vector embeddings generated from the inputText:

{
    "inference_results": [
    {
        "output": [
        {
            "name": "response",
            "dataAsMap": {
            "embedding": [
                0.6328125,
                0.26953125,
                0.41796875,
                -0.00579833984375,
                1.859375,
                0.2734375,
                0.130859375,
                -0.001007080078125,
                0.138671875,
                ...],
            "inputTextTokenCount": 2
            }
        }
        ],
        "status_code": 200
    }
    ]
}

Step 1: Create an ingest pipeline

Create an ingest pipeline to generate vector embeddings from text fields during document indexing. The input_map maps document fields to model inputs. In this example, the text source field in a document is mapped to the inputText field—the expected input field for the model. The output_map maps model outputs to document fields. In this example, the embedding output field from the model is mapped to the text_embedding destination field in your document:

PUT /_ingest/pipeline/knn_pipeline
{
  "description": "knn_pipeline",
  "processors": [
    {
      "ml_inference": {
        "model_id": "Sz-wFZQBUpPSu0bsJTBG",
        "input_map": [
          {
            "inputText": "text"
          }
        ],
        "output_map": [
          {
            "text_embedding": "embedding"
          }
        ]
      }
    }
  ]
}

Step 2: Index a document

Index the following document into a template-knn-1 index:

PUT /template-knn-1/_doc/1
{
  "text": "red shoes"
}

To view the document, send a GET request:

GET /template-knn-1/_doc/1

The response shows that the embeddings generated by the model are stored in the text_embedding field along with the original text:

{
    "_index": "template-knn-1",
    "_id": "1",
    "_version": 2,
    "_seq_no": 1,
    "_primary_term": 1,
    "found": true,
    "_source": {
    "text_embedding": [
        -0.69140625,
        0.8125,
        0.51953125,
        -0.7421875,
        0.6875,
        0.4765625,
        -0.34375,
        ...],
    "text": "red shoes"
    }
}

Step 3: Search using a template query

Use the following template query to search the index. The ml_inference processor generates a vector embedding from the input text sneakers, replaces ${text_embedding} with the generated vector, and searches for documents closest to the vector:

GET /template-knn-1/_search?search_pipeline=my_knn_pipeline
{
  "query": {
    "template": {
      "knn": {
        "text_embedding": {
          "vector": "${text_embedding}",
          "k": 2
        }
      }
    }
  },
  "ext": {
    "ml_inference": {
      "text": "sneakers"
    }
  }
}

The response contains the matching document:

{
    "took": 611,
    "timed_out": false,
    "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
    },
    "hits": {
    "total": {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 0.0019327316,
    "hits": [
        {
        "_index": "template-knn-1",
        "_id": "1",
        "_score": 0.0019327316,
        "_source": {
            "text_embedding": [
            -0.69140625,
            0.8125,
            0.51953125,
            ..],
            "text": "red shoes"
        }
        }
    ]
    }
}
350 characters left

Have a question? .

Want to contribute? or .