Skip to content

Commit

Permalink
Full code for esql article (#787)
Browse files Browse the repository at this point in the history
* full code for esql article

* build dependent on main project

* code style fixes
  • Loading branch information
l-trotta authored Apr 24, 2024
1 parent 16bfa28 commit 90b20ff
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 1 deletion.
34 changes: 34 additions & 0 deletions examples/esql-article/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
plugins {
id("java")
}

java {
targetCompatibility = JavaVersion.VERSION_17
}

repositories {
mavenCentral()
}

dependencies {
implementation(project(":java-client"))
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.17.0")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package co.elastic.clients.esql.article;

public record Book(
String title,
String description,
String author,
Integer year,
String publisher,
Float ratings
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package co.elastic.clients.esql.article;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._helpers.bulk.BulkIngester;
import co.elastic.clients.elasticsearch._helpers.esql.jdbc.ResultSetEsqlAdapter;
import co.elastic.clients.elasticsearch._helpers.esql.objects.ObjectsEsqlAdapter;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

public class EsqlArticle {

public static void main(String[] args) throws IOException, SQLException {
String dir = System.getProperty("user.dir");
Properties prop = new Properties();
Path path = Paths.get(dir, "examples", "esql-article", "src", "main", "resources", "application" +
".conf");
prop.load(new FileInputStream(path.toString()));

String serverUrl = prop.getProperty("server-url");
String apiKey = prop.getProperty("api-key");
String csvPath = prop.getProperty("csv-file");

RestClient restClient = RestClient
.builder(HttpHost.create(serverUrl))
.setDefaultHeaders(new Header[]{
new BasicHeader("Authorization", "ApiKey " + apiKey)
})
.build();

ObjectMapper mapper = JsonMapper.builder()
.build();

JacksonJsonpMapper jsonpMapper = new JacksonJsonpMapper(mapper);

ElasticsearchTransport transport = new RestClientTransport(
restClient, jsonpMapper);

ElasticsearchClient client = new ElasticsearchClient(transport);

if (!client.indices().exists(ex -> ex.index("books")).value()) {
client.indices()
.create(c -> c
.index("books")
.mappings(mp -> mp
.properties("title", p -> p.text(t -> t))
.properties("description", p -> p.text(t -> t))
.properties("author", p -> p.text(t -> t))
.properties("year", p -> p.short_(s -> s))
.properties("publisher", p -> p.text(t -> t))
.properties("ratings", p -> p.halfFloat(hf -> hf))
));
}

Instant start = Instant.now();
System.out.println("Starting BulkIndexer... \n");

CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = CsvSchema.builder()
.addColumn("title") // same order as in the csv
.addColumn("description")
.addColumn("author")
.addColumn("year")
.addColumn("publisher")
.addColumn("ratings")
.setColumnSeparator(';')
.setSkipFirstDataRow(true)
.build();

MappingIterator<Book> it = csvMapper
.readerFor(Book.class)
.with(schema)
.readValues(new FileReader(csvPath));

BulkIngester ingester = BulkIngester.of(bi -> bi
.client(client)
.maxConcurrentRequests(20)
.maxOperations(5000));

boolean hasNext = true;

while (hasNext) {
try {
Book book = it.nextValue();
ingester.add(BulkOperation.of(b -> b
.index(i -> i
.index("books")
.document(book))));
hasNext = it.hasNextValue();
} catch (JsonParseException | InvalidFormatException e) {
// ignore malformed data
}
}

ingester.close();

client.indices().refresh();

Instant end = Instant.now();

System.out.println("Finished in: " + Duration.between(start, end).toMillis() + "\n");

String query =
"""
from books
| where author == "Isaac Asimov"
| sort year desc
| limit 10
""";
List<Book> queryRes = (List<Book>) client.esql().query(ObjectsEsqlAdapter.of(Book.class), query);

System.out.println("~~~\nObject result:\n" + queryRes.stream().map(Book::title).collect(Collectors.joining("\n")));

ResultSet resultSet = client.esql().query(ResultSetEsqlAdapter.INSTANCE, query);

System.out.println("~~~\nResultSet result:");
while (resultSet.next()) {
System.out.println(resultSet.getString("title"));
}
}
}
3 changes: 3 additions & 0 deletions examples/esql-article/src/main/resources/application.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
server-url=elasticsearch-server-url
api-key=elasticsearch-api-key
csv-file=/path/to/your/csv/books.csv
9 changes: 8 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import java.nio.file.Paths

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
Expand All @@ -20,7 +22,8 @@
rootProject.name = "elasticsearch-java"

// Include as subprojects all subdirectories that have a "build.gradle.kts" and no ".gradle-standalone"
(rootProject.projectDir.listFiles() ?: arrayOf<File>()).
fun listFiles(dir: File){
(dir.listFiles() ?: arrayOf<File>()).
filter { File(it, "build.gradle.kts").exists() }.
filter { !File(it, ".gradle-standalone").exists() }.
filter { it.name != "buildSrc" }.
Expand All @@ -29,3 +32,7 @@ rootProject.name = "elasticsearch-java"
include(dir.name)
project(":" + dir.name).projectDir = dir
}
}

listFiles(rootProject.projectDir)
listFiles(Paths.get(rootProject.projectDir.path,"examples").toFile())

0 comments on commit 90b20ff

Please sign in to comment.