In implementing Elasticsearch API using Java The basic usage is also in Qiita and in the official reference, but I decided to write this article because there are few articles that are a little complicated or have more practical description or code.
--Those who want to or plan to develop using Elasticsearch API in Java --Elasticsearch beginners
--Elasticsearch API version: 7.3.2 --Java version: 8 --Spring Boot version: 1.5.15 --maven version: 2.17
pom.xml
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.3.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.3.2</version>
</dependency>
With the above description, you can use the Elasticsearch library.
* All the column names, field names, IDs, etc. that appear after that do not actually exist. </ font>
SearchRequest When translating the reference English
SearchRequest is used for operations that search for documents, aggregates, and suggestions, and also provides a way to request highlighting of the resulting document.
It says, but I think it's like a masterpiece for sending requests to Elasticsearch using the API.
java
SearchRequest searchRequest = new SearchRequest();
Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-search.html
SearchSourceBuilder
SearchSourceBuilder
is for adding search parameters.
java
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-search.html
RestHighLevelClient RestHighLevelClient is a REST client recommended to replace the previously used Transport Client. By using it, you can access Elasticsearch from your Java app via http.
java
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("user", "password")
);
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "https"))
.setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder
.setDefaultCredentialsProvider(credentialsProvider))
);
searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/_basic_authentication.html
function score query In the function score query, multiple conditions (functions) can be described in the functions section, and sorting is performed using the sum of the scores for each condition.
Just an example
FunctionScoreQueryBuilder functionScoreQueryBuilder = null;
ArrayList<FunctionScoreQueryBuilder.FilterFunctionBuilder> functionScoreArrayList = new ArrayList<>();
//You can add more than one
filterFunctionList.add(
new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("FashionItemId", "1"),
ScoreFunctionBuilders.fieldValueFactorFunction("custom_score.").factor(Float.valueOf("0.0254389"
)).missing(0.2)));
//ArrayList type to FunctionScoreQueryBuilder.FilterFunctionBuilder[]To
FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = functionScoreArrayList.toArray(new FunctionScoreQueryBuilder.FilterFunctionBuilder[functionScoreArrayList.size()]);
functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, functions).scoreMode(FunctionScoreQuery.ScoreMode.SUM).boostMode(CombineFunction.REPLACE);
searchSourceBuilder.query(functionScoreQueryBuilder);
Reference: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html
count
It can be specified as .count
for RestHighLevelClient.
java
CountResponse countResponse = null;
countResponse = restHighLevelClient.count(searchRequest, RequestOptions.DEFAULT);
Then, you can get the number of hits in searchRequest in the form of CountResponse.
Reference: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html
search
It can be specified with .search
for RestHighLevelClient.
java
SearchResponse searchResponse = null;
searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Then, you can get the search results that hit searchRequest in the form of SearchResponse.
Reference: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
_source
Elasticsearch's _source
is like a SELECT clause in SQL.
In the case of API, specify the field to fetch using fetchSource.
By narrowing down the fields to be acquired, the amount of data can be reduced, so speed improvement can be expected.
Specify the field to be acquired in the first argument and the field to be excluded in the second argument.
In the case of count mentioned above, it is okay without specifying.
java
searchSourceBuilder.fetchSource(new String[]{"FashionItemId", "ItemPrice", "FashionItemSize",
"FashionItemLargeCategory", "FashionItemSmallCategory"},
"ExclusionFashionItemId");
Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-search.html#_source_filtering
Sort It is Order By in SQL. Use FieldSortBuilder to specify the sort.
When sorting by multiple columns
return searchSourceBuilder.sort(new FieldSortBuilder("ItemPrice").order(SortOrder.ASC))
.sort(new FieldSortBuilder("FashionItemId").order(SortOrder.DESC))
.sort(new FieldSortBuilder("StartDatetime").order(SortOrder.DESC));
Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-search.html#_specifying_sorting
from & size
It corresponds to offset & limit in SQL.
You can specify it with .from`` .to
for SearchSourceBuilder mentioned above.
java
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.from(0);
searchSourceBuilder.size(100);
Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-search.html#_using_the_searchsourcebuilder
BoolQuery Used to combine other queries. You can combine AND, OR, NOT. There are four types of BoolQuery.
Query | Description |
---|---|
must | It is AND in SQL. The score will be calculated according to the specified conditions. |
filter | It is AND in SQL. Unlike must, the score is not calculated. |
should | It is OR in SQL. |
must not | It is NOT in SQL. |
termQuery Whether it matches. In SQL = (equal) Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.8/query-dsl-term-query.html
temrsQuery Is there a match? IN clause in SQL Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-term-level-queries.html#java-query-dsl-terms-query
rangeQuery Is there a specified range? > =, <=, <,> In SQL Reference: https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-term-level-queries.html#java-query-dsl-range-query
For SQL
AND StartDatetime >= '2019-12-06 17:33:18'
AND (
(
FashionItemLargeCategory <> 1
AND FashionItemSmallCategory NOT IN (10,20,30)
AND FashionItemSize IN (1,2)
) OR (
(
FashionItemLargeCategory = 2
OR FashionItemSmallCategory IN (40,50,60)
)
AND FashionItemSize IN (9,10)
)
)
For Elasticsearch
"bool": {
"filter": [
{
"range": {
"StartDatetime": {
"from": null,
"to": "2019-12-06 17:33:18",
"include_lower": true,
"include_upper": false
}
}
},
{
"bool": {
"filter": [
{
"bool": {
"should": [
{
"bool": {
"filter": [
{
"terms": {
"FashionItemSize ": [
1,
2
]
}
}
],
"must_not": [
{
"term": {
"FashionItemLargeCategory ": {
"value": 1,
"boost": 1
}
}
},
{
"terms": {
"FashionItemSmallCategory ": [
10,
20,
30
]
}
}
]
}
},
{
"bool": {
"filter": [
{
"terms": {
"FashionItemSize": [
9,
10
]
}
}
],
"should": [
{
"term": {
"FashionItemLargeCategory ": {
"value": 1
}
}
},
{
"terms": {
"FashionItemSmallCategory ": [
40,
50,
60
]
}
}
]
}
}
]
}
}
]
}
}
]
}
(It's very complicated and hard to see ...)
For java
integer[] smallCategories1 = {10, 20, 30};
integer[] itemSize1 = {1, 2};
integer[] smallCategories2 = {40, 50, 60};
integer[] itemSize2 = {9, 10};
BoolQueryBuilder qb1 = boolQuery()
.mustNot(termQuery("FashionItemLargeCategory", 1))
.mustNot(termsQuery("FashionItemSmallCategory", smallCategories1))
.filter(termsQuery("FashionItemSize" , itemSize1));
BoolQueryBuilder qb2 = boolQuery()
.should(termQuery("FashionItemLargeCategory", 2))
.should(termsQuery("FashionItemSmallCategory", smallCategories2))
.filter(termsQuery("FashionItemSize", itemSize2));
BoolQueryBuilder qb3 = boolQuery()
.should(qb1)
.should(qb2);
BoolQueryBuilder qb4 = boolQuery()
.filter(rangeQuery("StartDatetime").from(null).lt("2019-12-06 17:33:18"))
.filter(qb3);
You can get Elasticsearch query by doing toString () to BoolQueryBuilder. Check if the query is correct by comparing the result with the expected query or hitting it with Kibana.
Example (SQL vs ElasticSearch vs Java) When validating BoolQueryBuilder queries
System.out.println(qb4.toString());
This article is just the information at the time when I first touched it. At that time, there were few articles, but nowadays, if you look it up, there may be many good articles. I hope it will be helpful for those who are new to the Elasticsearch API.
Recommended Posts