31 Mayıs 2023 Çarşamba

List.subList metodu

Sabit Büyüklüğe Ayırmak
Partition by Size diyelim
Örnek
Şöyle yaparız
public static <T> List<List<T>> partitionList(List<T> list, int partitionSize) {
  List<List<T>> partitionedList = new ArrayList<>();
  int size = list.size();

  for (int i = 0; i < size; i += partitionSize) {
    int end = Math.min(size, i + partitionSize);
    partitionedList.add(list.subList(i, end));
  }
  return partitionedList;
}
Örnek - Guava
Lists.partition() kullanılabilir

Örnek - Apache Commons
ListUtils.partition() kullanılabilir

Sabit Sayıda Parçalara Ayırmak
Number of Partitions diyelim
Örnek
Şöyle yaparız. Listeyi 6 parçaya ayırırız
List<Integer> mylist = ...
int size = mylist.size();
int parts = 6;
int partSize = size / parts;
List<List<Integer>> result = 
    IntStream.range(0, parts)
             .mapToObj(i -> mylist.subList(i * partSize, (i + 1) * partSize)))
             .collect(Collectors.toList());

30 Mayıs 2023 Salı

ArchUnit ClassFileImporter Sınıfı

Giriş
Şu satırı dahil ederiz
import com.tngtech.archunit.core.importer.ClassFileImporter;
importPackages metodu
Açıklaması şöyle
The returned object of type JavaClasses represents a collection of elements of type JavaClass, where JavaClass in turn represents a single imported class file. You can in fact access most properties of the imported class via the public API
Yani şöyle yapabiliriz
JavaClass clazz = classes.get(Object.class);
System.out.print(clazz.getSimpleName()); // returns 'Object'
Örnek
Şöyle yaparız
JavaClasses jc = new ClassFileImporter()
  .importPackages("com.baeldung.archunit.smurfs");


26 Mayıs 2023 Cuma

Monad

Giriş
Functional dillerde Monad, Function Composition için kullanılır

Örnek
Şöyle yaparız
bread = bake( mill(wheat) )
Java'da Monad yok. Ancak benzer bir sonucu iki farklı şekilde yapabiliriz.

1. Chaining Methods
2. Optional Kullanarak

1. Chaining Methods
Örnek
Şöyle yaparız
public Optional<Flour> mill(Wheat wheat) {
   // ...
}

public Optional<Bread> bake(Flour flour) {
   // ...
}

Optional<Bread> oopBread = harvest()
      .flatMap(wheat -> mill(wheat))
      .flatMap(flour -> bake(flour));
2. Optional Kullanarak
Diğer dillerde Maybe<>, Either<>, Optional<> gibi yapılar var Java'da sadece Optional var. Bu kullanım biraz daha Functional dillere benziyor. Ancak halen exception handling sıkıntısı var. Three Exception-Handling Alternatives Inspired by Functional Programming yazısına bakabilirsiniz

Örnek
Şöyle yaparız
public Optional<Flour> mill(Optional<Wheat> wheat) {
   // ...
}

public Optional<Bread> bake(Optional<Flour> flour) {
   // ...
}

Optional<Bread> fpBread = bake( mill( harvest() ) );

Reading Large Tables In Batches

1. SpringBoot Kullanıyorsak
PageRequest kullanılabilir
Örnek
Şöyle yaparız
PageRequest pageRequest = PageRequest.of(0,10);
Page<Account> page; List<Account> list; do { page = accountRepository.findAll(pageRequest); list = page.getContent(); page = page.next(); } while (!page.isEmpty());
2. JPA Kullanıyorsak
TypedQuery kullanılabilir
Örnek
Şöyle yaparız
int startPosition = 0;
int batchSize = 10;

while(true) {

  TypedQuery<Account> query = em.createQuery("SELECT a FROM Account a", Account.class);
  query.setFirstResult(startPosition);
  query.setMaxResults(batchSize_size);
  
   List<Account> list = query.resultList();
    if (list.size() == 0) {
      break;
    }
    startPosition += batchSize; 
}
3. SQL ile Offset + Limit
TypedQuery kullanılabilir
Örnek
Şöyle yaparız
Session session = em.unwrap(Session.class);
session.doReturningWork(new ReturningWork<>() {
    @Override
    public Integer execute(Connection connection) throws SQLException {
      int offsetPos = 0;
      
      PreparedStatement preparedStatement = connection
                .prepareStatement("SELECT * FROM ACCOUNTS LIMIT ? OFFSET ?");
      while (true) {
        preparedStatement.setInt (1, 10);
        preparedStatement.setInt (2, offsetPos);
        ResultSet resultSet = preparedStatement.executeQuery();
        if(!resultSet.next()) break; // break when finish reading
        do {
          System.out.println(resultSet.getString("user_id"));
        } while (resultSet.next());
        offsetPos += 10;
      }
    }
}
4. Statement.setFetchSize kullanılabilir
JDBC Statement Arayüzü yazısına bakınız


23 Mayıs 2023 Salı

Reading Large Files Line By Line

Giriş
Kullanılabilecek yöntemler şöyle
1. Files Sınıfı
2. BufferedReader Sınıfı
3. Scanner Sınıfı

Test İçin Büyük Dosya Yaratmak
Şöyle yaparız
public void prepFile() throws IOException {
  BufferedWriter bufferedWriter = Files.newBufferedWriter(Path.of(TARGET_FILE),
    StandardOpenOption.CREATE);
  IntStream.rangeClosed(1,100000000)
    .forEach(a-> write(bufferedWriter, a));
  bufferedWriter.flush();
}

public void write(BufferedWriter bufferedWriter, int a) {
  try {
    bufferedWriter.write(a + "\n");
  } catch (IOException e) {
    ...
    throw new RuntimeException(e);
  }
}
1. Files Sınıfı
Örnek
Şöyle yaparız
Path filePath = Paths.get("C:/temp/file.txt")
 
//try-with-resources
try (Stream<String> lines = Files.lines( filePath )) {
  lines.forEach(...); // Process the line
} catch (IOException e) { ... }
2. BufferedReader Sınıfı
Bu sınıf 2 şekilde kullanılabilir.
1. lines metodu
2. readLine metodu

lines metodu
Aslında bunun yerine Files.lines() çok daha kolay

Örnek
Şöyle yaparız
public void usingBufferedReaderAndLambda() throws IOException {
  try (BufferedReader bufferedReader = Files.newBufferedReader(Path.of(TARGET_FILE))) {
    bufferedReader.lines()
    .forEach(...);  // Process the line
  }
}
readLine metodu
Örnek
Şöyle yaparız
public void usingBufferedReader() throws IOException {
  try(FileReader fileReader = new FileReader(new File(TARGET_FILE))){
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    String readLine;
    while((readLine = bufferedReader.readLine())!=null){
      // Process the line
    }
  }
}
3. Scanner Sınıfı
Bir örnek burada


Eski ElasticSearchHighLevel IndicesClient Sınıfı

exists metodu
Örnek
Şöyle yaparız
GetIndexRequest request = new GetIndexRequest(props.getIndex().getName());
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);

if (!exists) {
  CreateIndexRequest indexRequest = new CreateIndexRequest(props.getIndex().getName());
  indexRequest.settings(Settings.builder()
       .put("index.number_of_shards", props.getIndex().getShard())
       .put("index.number_of_replicas", props.getIndex().getReplica())
  );

  CreateIndexResponse createIndexResponse = client.indices()
    .create(indexRequest, RequestOptions.DEFAULT);
  if (createIndexResponse.isAcknowledged()&& createIndexResponse.isShardsAcknowledged()) {
      log.info("{} index created successfully", props.getIndex().getName());
  } else {
    log.debug("Failed to create {} index", props.getIndex().getName());
  }
}

22 Mayıs 2023 Pazartesi

JUL FileHandler Sınıfı

Örnek
Şöyle yaparız
private static final Logger LOGGER = Logger.getLogger(JULExample.class.getName());

public static void main(String[] args) {
  LOGGER.setUseParentHandlers(false); // Disable default console handler
  ConsoleHandler consoleHandler = new ConsoleHandler();
  consoleHandler.setLevel(Level.INFO);
  LOGGER.addHandler(consoleHandler);

  try {
    FileHandler fileHandler = new FileHandler("mylog.log", true);
    fileHandler.setFormatter(new SimpleFormatter());
    fileHandler.setLevel(Level.WARNING);
    LOGGER.addHandler(fileHandler);
  } catch (IOException e) {
    LOGGER.severe("Failed to create log file: " + e.getMessage());
  }

  LOGGER.info("Starting application...");

  try {
    int result = 10 / 0;
  } catch (ArithmeticException e) {
    LOGGER.log(Level.SEVERE, "An error occurred", e);
  }

  LOGGER.warning("this is a warning message");
  LOGGER.info("Application finished.");
}


JUL Konfigürasyon Dosyası

Giriş
Varsayılan dosyanın yolu şöyledir.
jre\lib\logging.properties
JVM parametresi olarak vermek için şöyle yaparız.
-Djava.util.logging.config.file="logging.properties" 
Kodla şöyle yaparız
public static void main(String[] args) throws IOException {
  // Load the logging configuration file
  InputStream configStream = JULExample.class.getResourceAsStream("/jul.properties");
  LogManager.getLogManager().readConfiguration(configStream);

  // Get a logger for our application
  Logger logger = Logger.getLogger(JULExample.class.getName());

  // Log a message
  logger.finest("This is a FINEST message.");
  logger.finer("This is a FINER message.");
  logger.fine("This is a FINE message.");
  logger.config("This is a CONFIG message.");
  logger.info("This is an INFO message.");
  logger.warning("This is a WARNING message.");
  logger.severe("This is a SEVERE message.");
}
.level Alanı
Global olarak loglama seviyesini belirtir.
Örnek
Şöyle yaparız
.level= INFO
Örnek
Şöyle yaparız
# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers.  For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= INFO
Örnek
Şöyle yaparız
handlers= java.util.logging.ConsoleHandler
.level= INFO

# Set the console handler properties
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

## Set the logger level to WARNING
com.example.javasandbox.logging.JULExample.level = WARNING
Örnek
Belli bir sınıfı değiştirmek için şöyle yaparız.
com.xyz.foo.level = SEVERE
Örnek
Şöyle yaparız.
mylogger.level=NONE

21 Mayıs 2023 Pazar

JEP 430 - String Interpolation veya String Templates - JDK 21 İle Geliyor

Giriş
Açıklaması şöyle
Java provides three predefined templates for this purpose RAW, STR and FMT. 
1. STR string interpolation yapar
2. FMT string interpolation ve custom formatting yapar 

1. STR
Açıklaması şöyle
The new way to work with Strings in Java is called template expression, a programmable way of safely interpolating expressions in String literals. And even better than just interpolating, we can turn structured text into any object, not just a String.

The create a template expression, we need two things:

1. A template processor
2. A template containing wrapped expressions like \{name}
Açıklaması şöyle. Formatlamak istenilen değişken string içinde \{variable_name} şeklinde kullanılır
The prefix STR is the string template provided by Java for the string composition and interpolation. 
Örnek
Şöyle yaparız
String name = "Joan";

String info = STR."My name is \{name}";
assert info.equals("My name is Joan");   // true
Örnek - Invoke Methods
Şöyle yaparız
var name = "Ben";
var tempC = 28;

var greeting = STR."Hello \{this.user.firstname()}, how are you?\nIt's \{tempC}°C today!";
Örnek - Invoke Methods and Access Fields
Şöyle yaparız
String s = STR."You have a \{getOfferType()} waiting for you!";
// s: "You have a gift waiting for you!"
String t = STR."Access at \{req.date} \{req.time} from \{req.ipAddress}";
// t: "Access at 2022-03-25 15:34 from 8.8.8.8"
Örnek - Arithmetic Operations
Şöyle yaparız
int x = 10, y = 20;
String s = STR."\{x} + \{y} = \{x + y}";
// s: "10 + 20 = 30"
Örnek - Evaluation Order
Şöyle yaparız
int index = 0;
String data = STR."\{index++}, \{index++}, \{index++}, \{index++}";
// data: "0, 1, 2, 3"

Örnek - Double Quotes
Şöyle yaparız
String filePath = "tmp.dat";
File file = new File(filePath);
String msg = STR."The file \{filePath} \{file.exists() ? "does" : "does not"} exist";

Multi-Line Templates and Expressions
Java text blocks kullanılabilir
Örnek - Invoke Methods
Şöyle yaparız
String time = STR."The time is \{
    // The java.time.format package is very useful
    DateTimeFormatter
      .ofPattern("HH:mm:ss")
      .format(LocalTime.now())
} right now";
// time: "The time is 12:34:56 right now"
Örnek - HTML
Şöyle yaparız
String title = "My Web Page";
String text  = "Hello, world";
String html = STR."""
        <html>
          <head>
            <title>\{title}</title>
          </head>
          <body>
            <p>\{text}</p>
          </body>
        </html>
        """;
| """
| <html>
|   <head>
|     <title>My Web Page</title>
|   </head>
|   <body>
|     <p>Hello, world</p>
|   </body>
| </html>
| """
Örnek - JSON
Şöyle yaparız
String name    = "Joan Smith";
String phone   = "555-123-4567";
String address = "1 Maple Drive, Anytown";
String json = STR."""
    {
        "name":    "\{name}",
        "phone":   "\{phone}",
        "address": "\{address}"
    }
    """;
| """
| {
|     "name":    "Joan Smith",
|     "phone":   "555-123-4567",
|     "address": "1 Maple Drive, Anytown"
| }
| """
Örnek
Şöyle yaparız. Expression değişkenleri de çoklu satır şeklinde kullanılabiliyor.
var json = STR."""
{
    "user": "\{this.user.firstname()}",
    "temperatureCelsius: \{tempC}
}
""";

// Not only the template itself can be multi-line, expressions can be too, 
// including comments!
var json = STR."""
{
  "user": "\{
    // We only want to use the firstname
    this.user.firstname()
  }",
  "temperatureCelsius: \{tempC}
}
""";

2. FMT
Açıklaması şöyle. Formatlamak istenilen değişken string içinde %formatter\{variable_name} şeklinde kullanılır
FMT is another processor which is like the STR but also interprets the formats specified in expression
Örnek
Şöyle yaparız
String formatted = FMT."The price is: \{price, number, currency}";
// formatted: "The price is: $50.00"

Örnek - %12s
Şöyle yaparız
rrecord Rectangle(String name, double width, double height) {
  double area() {
    return width * height;
  
}
Rectangle[] zone = new Rectangle[] {
  new Rectangle("Alfa", 17.8, 31.4),
  new Rectangle("Bravo", 9.6, 12.4),
  new Rectangle("Charlie", 7.1, 11.23),
};
String table = FMT."""
    Description     Width    Height     Area
    %-12s\{zone[0].name}  %7.2f\{zone[0].width}  %7.2f\{zone[0].height}     %7.2f\{zone[0].area()}
    %-12s\{zone[1].name}  %7.2f\{zone[1].width}  %7.2f\{zone[1].height}     %7.2f\{zone[1].area()}
    %-12s\{zone[2].name}  %7.2f\{zone[2].width}  %7.2f\{zone[2].height}     %7.2f\{zone[2].area()}
    \{" ".repeat(28)} Total %7.2f\{zone[0].area() + zone[1].area() + zone[2].area()}
    """;
| """
| Description     Width    Height     Area
| Alfa            17.80    31.40      558.92
| Bravo            9.60    12.40      119.04
| Charlie          7.10    11.23       79.73
|                              Total  757.69
| """
3. RAW
Örnek ver



17 Mayıs 2023 Çarşamba

Eski ElasticSearchHighLevel RestHighLevelClient Sınıfı

Giriş
Şu satırı dahil ederiz
import org.elasticsearch.client.RestHighLevelClient;
Açıklaması şöyle
The Elasticsearch High Level REST Client, which was a popular choice for interacting with Elasticsearch clusters, has been deprecated since version 7.7.0. 

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.elasticsearch.client</groupId>
  <artifactId>elasticsearch-rest-high-level-client</artifactId>
  <version>7.14.0</version>
</dependency>
constructor -RestClientBuilder
Şöyle yaparız
@Bean(destroyMethod = "close")
public RestHighLevelClient getRestClient() {
  return new RestHighLevelClient(RestClient.builder(new HttpHost(hostName,
    httpPort, scheme)));
}
delete metodu
Örnek
Şöyle yaparız
DeleteRequest deleteRequest = new DeleteRequest(props.getIndex().getName(), id);
client.delete(deleteRequest, RequestOptions.DEFAULT);
index metodu
Örnek
Şöyle yaparız
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("user", "kimchy");
jsonMap.put("postDate", new Date());
jsonMap.put("message", "trying out Elasticsearch");
IndexRequest indexRequest = new IndexRequest("myIndex")
                             .id("1").source(jsonMap);

IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
Örnek
Eğer JSON göndermek istersek şöyle yaparız
IndexRequest indexRequest = new IndexRequest("myIndex")
                             .id("1")
String jsonString = "{" +
   "\"user\":\"kimchy\"," +
   "\"postDate\":\"2013-01-30\"," +
   "\"message\":\"trying out Elasticsearch\"" +
   "}";
indexRequest.source(jsonString, XContentType.JSON);

IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
Örnek
Şöyle yaparız
public String indexRequest(Foo foo){
  try {
    IndexRequest indexRequest = new IndexRequest("myIndex")
      .id(foo.getId())
      .source(XContentType.JSON,"title", foo.getTitle(),
          "subject", foo.getSubject(),
          "content", foo.getContent());
      IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
      return response.getId();
  } catch (Exception ex) {
    ...
  }
  return null;
}
indices metodu
IndicesClient nesnesi döner

search metodu
Örnek
Şöyle yaparız
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

SearchSourceBuilder sourceBuilder = ...;

public List<Document> wildcardQuery(String query) {
  List<Foo> result = new ArrayList<>();
  try {
    AbstractQueryBuilder builder = QueryBuilders
      .queryStringQuery("*" + query.toLowerCase() + "*")
    result = getDocuments(builder);
  } catch (Exception ex) {...}
  return result;
}

List<Document> getDocuments(AbstractQueryBuilder builder) throws IOException {
  List<Foo> result = new ArrayList<>();

  sourceBuilder.query(builder);

  SearchRequest searchRequest = new SearchRequest("myIndex");
  searchRequest.source(sourceBuilder);

  SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  SearchHits hits = searchResponse.getHits();
  SearchHit[] searchHits = hits.getHits();
  for (SearchHit hit : searchHits) {
    Foo foo = gson.fromJson(hit.getSourceAsString(), Foo.class);
    foo.setId(hit.getId());
    result.add(foo);
  }
  return result;
}

update metodu
Örnek
Şöyle yaparız
public String updateDocument(Foo foo){
  try {
    UpdateRequest request = new UpdateRequest("myIndex", foo.getId())
      .doc(gson.toJson(foo), XContentType.JSON);
    UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
    return response.getId();
  } catch (Exception ex){
    ...
  }
  return null;
}

NavigableSet Arayüzü - SortedSet Gibidir

Giriş
Şu satırı dahil ederiz
import java.util.NavigableSet;
NavigableSet  aynı zamanda bir SortedMap. Kalıtım hiyerarşisi şöyle:
SortedSet <---NavigableSet<--TreeSet
tailSet metodu
Örnek
Şöyle yaparız
NavigableSet<Integer> numbers = new TreeSet<>(Arrays.asList(1, 2, 3, 4, 5));
NavigableSet<Integer> tailSet = numbers.tailSet(3, true); //inclusive: true

// Returns {3, 4, 5}


15 Mayıs 2023 Pazartesi

ElasticSearch Java API Client ElasticsearchIndicesClient Sınıfı

Giriş
Açıklaması şöyle
All indices related operations form a namespace called “indices”, hence classes and a client related to operations on indices are present in co.elastic.clients.elasticsearch.indices package. As expected, the client supporting the “indices” operations is the ElasticearchIndicesClient. To obtain this client, one must ask the main Java API client (the ElasticsearchClient) to provide the instance of the indices client. 
constructor
Şöyle yaparız
ElasticsearchIndicesClient elasticsearchIndicesClient = elasticsearchClient.indices();
create metodu
Açıklaması şöyle
Once we have the respective client, like ElasticsearchIndicesClient, we can invoke create() method to create an index. The create() method expects a Request object — a CreateIndexRequest object to be precise. This pattern leads to our next request/response pattern.

All methods on the client are expected to be passed in with a request object. As you can expect there are a lot of request classes. Each of these request objects are instantiated using the builder pattern.

Take an example of “creating an index” use case. This requires a CreateIndexRequest to be instantiated with arguments that are required to create an index. 
...

The index() method accepts a string as the name of the index. Once we have the index created, we can then invoke the create method on the indices client by passing this request. 
...

The result of this invocation is captured in the response object: CreateIndexResponse in this case. Again, any invocation will return a response — it follows the same pattern — for example: the CreateIndexRequest’s response would be CreateIndexResponse object. The response object would have all the required information about the newly created index.
Örnek
Şöyle yaparız
CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder()
  .index("flights")
  .build();

CreateIndexResponse createIndexResponse = elasticsearchIndicesClient
  .create(createIndexRequest);


ElasticSearch Java API Client ElasticsearchClient Sınıfı

Giriş
Şu satırı dahil ederiz
import co.elastic.clients.elasticsearch.ElasticsearchClient;
Sanırım RestHighLevelClient yerine bu Java client kullanılmalı

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>co.elastic.clients</groupId>
  <artifactId>elasticsearch-java</artifactId>
  <version>8.5.3</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.12.7</version>
</dependency>
Gradle
Şu satırı dahil ederiz
dependencies {
  implementation 'co.elastic.clients:elasticsearch-java:8.5.3'
  implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.7'
}
constructor
Açıklaması şöyle
The client class is co.elastic.clients.elasticsearch.ElasticsearchClient which is initialized by providing the transport object (co.elastic.clients.transport.ElasticsearchTransport) to its constructor. This transport object in turn needs the restclient and JSON mapper objects.
Örnek
Şöyle yaparız
# Step 1: create the RestClient
RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build();

# Step 2: Construct the ElasticsearchTransport object

# Create a new JacksonJsonpMapper object
JacksonJsonpMapper jsonMapper = new JacksonJsonpMapper();

# Create the transport object
ElasticsearchTransport elasticsearchTransport =
   new RestClientTransport(restClient, jsonMapper);

# Step 3: Construct the ElasticsearchTransport object
ElasticsearchClient elasticsearchClient = new ElasticsearchClient(elasticsearchTransport);
Bulk Requests
Açıklaması şöyle
The Bulk API makes it possible to perform many index/delete operations in a single API call. This can greatly increase the
indexing speed. Each subrequest is executed independently, so the failure of one subrequest won’t affect the success of the others. If
any of the requests fail, the top-level error flag is set to true and the error details will be reported under the relevant request.

indices metodu

index metodu
Yaratılmış bir index'e doküman gönderir

Örnek
Şununla aynıdır
POST flights/_doc
{
  "route":"London to New York",
  "name":"BA123",
  "airline":"British Airways",
  "duration_hours":5
}
Şöyle yaparız
public void indexDocument(String indexName, Flight flight) throws IOException {
  IndexResponse indexResponse = this.elasticsearchClient.index(
    i -> i.index(indexName)
          .document(flight)
   );
   System.out.println("Document indexed" + indexResponse);
} 
Açıklaması şöyle
Executing this query will index a flight into our flights index. The elasticsearchClient exposes an index method that can be chained up with other methods such as id and document. In the above case, we didn’t use the ID as we’ve let the system generate it for us.

The document method expects the flight object; did you notice we didn’t do any transformation of the flight Java object to JSON? That’s because, we’ve delegated the responsibility of marshaling and unmarshaling to the JacsonJasonpMapper class that we associated with the transport object earlier on.
search metodu
Şöyle yaparız
SearchResponse searchResponse = 
elasticsearchClient.search(
 searchRequest -> searchRequest
   .index(indexName)
   .query(
     queryBuilder ->
       queryBuilder.match(
	     matchQBuilder->
		   matchQBuilder.field("route").query(searchText))
	), //query
	Flight.class
);
Daha sonra şöyle yaparız
// Capture flights
List<Flight> flights =  (List<Flight>) searchResponse.hits().hits()
  .stream()
  .collect(Collectors.toList());

// Or print them to the console
searchResponse.hits()
  .hits()
  .stream()
  .forEach(System.out::println);
Açıklaması şöyle
Searching data using queries with Java API client follows the similar path — invoking search method in the ElasticsearchClient class by passing the required query. There’s one subtle difference though — unlike the other features exposing a client per namespace, the search feature does not. That is, there’s no separate “client” per se, unlike ElasticsearchIndicesClient.

Let’s just say we wish to search for a route from London to New York: We create a match query providing the “London New York” as the search criteria against the route field in a nicely formed DSL when working with Kibana.

The search method is expecting a search request, it is provided as a lambda expression to the method as you see above. The query will be written using another lambda function — given a query request (Query.Builder object), invoke the match function with the MatchQuery.Builder object. The JSON will be converted to a Flight Java object, which is why Flight.class is provided as the argument to the query method.

The response from the search method is a SearchResponse — so we can capture the results ...

The searchResponse consists of results as hits — which can be iterated through to get to the list of Flights that were returned. 

As you can infer, the searchResponse object has the results in the hits array — all we need to make sure is to cast the hits to appropriate domain objects (Flight in this case).