﻿---
title: Searching for documents
description: Indexed documents are available for search in near real-time. There are many types of search queries that can be combined. We will start with the simple...
url: https://www.elastic.co/elastic/docs-builder/docs/3028/reference/elasticsearch/clients/java/usage/searching
products:
  - Elasticsearch
  - Elasticsearch Client
  - Elasticsearch Java Client
---

# Searching for documents
Indexed documents are available for search in near real-time.
<note>
  See the Elasticsearch documentation for a full explanation of search requests: [search your data](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/solutions/search/querying-for-search), [the query DSL](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/solutions/search/querying-for-search), and [search APIs](https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-search).
</note>


## Simple search query

There are many types of search queries that can be combined. We will start with the simple text match query, searching for bikes in the `products` index.
The search result has a `hits` properties that contains the documents that matched the query along with information about the total number of matches that exist in the index.
The total value comes with a relation that indicates if the total is exact (`eq`—equal) or approximate (`gte`—greater than or equal).
Each returned document comes with its relevance score and additional information about its location in the index.
```java

String searchText = "bike";

SearchResponse<Product> response = esClient.search(s -> s
    .index("products")
    .query(q -> q     
        .match(t -> t  
            .field("name") 
            .query(searchText)
        )
    ),
    Product.class     
);

TotalHits total = response.hits().total();
boolean isExactResult = total.relation() == TotalHitsRelation.Eq;

if (isExactResult) {
    logger.info("There are " + total.value() + " results");
} else {
    logger.info("There are more than " + total.value() + " results");
}

List<Hit<Product>> hits = response.hits().hits();
for (Hit<Product> hit: hits) {
    Product product = hit.source();
    logger.info("Found product " + product.getSku() + ", score " + hit.score());
}
```

Similarly to [get](https://www.elastic.co/elastic/docs-builder/docs/3028/reference/elasticsearch/clients/java/usage/reading) operations, you can fetch documents matching your query as raw JSON by using a corresponding target class instead of `Product`, like JSON-P’s `JsonValue` or Jackson’s `ObjectNode`.

## Nested search queries

Elasticsearch allows individual queries to be combined to build more complex search requests. In the example below we will search for bikes with a maximum price of 200.
```java
String searchText = "bike";
double maxPrice = 200.0;

// Search by product name
Query byName = MatchQuery.of(m -> m
    .field("name")
    .query(searchText)
)._toQuery();

// Search by max price
Query byMaxPrice = RangeQuery.of(r -> r
    .number(n -> n
    .field("price")
    .gte(maxPrice))
)._toQuery();

// Combine name and price queries to search the product index
SearchResponse<Product> response = esClient.search(s -> s
    .index("products")
    .query(q -> q
        .bool(b -> b
            .must(byName)
            .must(byMaxPrice)
        )
    ),
    Product.class
);

List<Hit<Product>> hits = response.hits().hits();
for (Hit<Product> hit: hits) {
    Product product = hit.source();
    logger.info("Found product " + product.getSku() + ", score " + hit.score());
}
```


## Templated search

A search template is a stored search that you can run with different variables. Search templates let you change your searches without modifying your application code.
Before running a template search, you first have to create the template. This is a stored script that returns the search request body, and is usually defined as a Mustache template. This stored script can be created outside the application, and also with the Java API Client:
```java
// Create a script
esClient.putScript(r -> r
    .id("query-script")
    .script(s -> s
        .lang("mustache")
        .source(so -> so.scriptString("{\"query\":{\"match\":{\"{{field}}\":\"{{value}}\"}}}"))
    ));
```

To use the search template, use the `searchTemplate` method to refer to the script and provide values for its parameters:
```java
SearchTemplateResponse<Product> response = esClient.searchTemplate(r -> r
        .index("some-index")
        .id("query-script")
        .params("field", JsonData.of("some-field"))
        .params("value", JsonData.of("some-data")),
    Product.class
);

List<Hit<Product>> hits = response.hits().hits();
for (Hit<Product> hit: hits) {
    Product product = hit.source();
    logger.info("Found product " + product.getSku() + ", score " + hit.score());
}
```

For more in-depth information, see the [Elasticsearch search template documentation](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/solutions/search/search-templates).
The source code for the examples above can be found in the [Java API Client tests](https://github.com/elastic/elasticsearch-java/tree/main/java-client/src/test/java/co/elastic/clients/documentation).