В предыдущей статье мы подробно описали общие операции индексации es и документов через визуальный интерфейс Kibana. В этой статье мы расскажем, как использовать Java для выполнения операций es, которые также будут задействованы в реальной разработке.
С появлением новой версии Elasticsearch 8.x концепция типа была отменена. Чтобы адаптироваться к этому изменению в структуре данных, официальные лица Elasticsearch рекомендуют использовать новый Java-клиент Elasticsearch, начиная с версии 7.15.
В настоящее время Java используется для управления es при разработке, будь то интеграция с инфраструктурой или чистое использование es api, в основном с помощью следующих двух методов:
rest-api, основные, такие как RestHighLevelClient;
Операции JPA при интеграции с Springboot в основном представляют собой API, связанные с ElasticsearchRepository;
Два вышеупомянутых режима API можно удобно использовать во время разработки. Напротив, API, связанный с RestHighLevelClient, более гибкий, а нижний уровень ElasticsearchRepository имеет большую инкапсуляцию, что упрощает его изучение и использование, а также ускоряет начало работы.
Далее мы сделаем подробный обзор двух вышеупомянутых режимов работы. Описанный в этой статье компьютер основан на версии 7.6.1, а соответствующий кибана также имеет версию 7.6.1.
Импортируйте основные зависимости, в основном остальные зависимости ES, а другие можно импортировать в соответствии с вашими потребностями. Брат Хонг напрямую вставляет сюда содержимое своего файла pom.xml.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ElasticSearch</groupId>
<artifactId>ElasticSearch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ElasticSearch</name>
<url>https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.6.1</version>
</dependency>
<!-- elasticsearch клиент -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.1</version>
</dependency>
<!-- elasticsearch полагаться 2.x из log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</project>
Создайте новый тестовый класс EsClientTest и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.apache.http.HttpHost;
import java.io.IOException;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EsClientTest {
//Проверяем соединение ES
// public static void main(String[] args) throws IOException {
// RestHighLevelClient esClient = new RestHighLevelClient(
// RestClient.builder(new HttpHost("IP",9200,"http"))
// );
// System.out.println("success");
// esClient.close();
// }
//Чтобы уменьшить количество кода, связанного с подключением, мы поместили ES-клиент в глобальную статическую переменную, на которую можно напрямую ссылаться в других методах.
public static ObjectMapper objectMapper = new ObjectMapper();
public static RestHighLevelClient esClient;
static {
esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));
}
}
Запустите приведенный выше код, и появится следующий эффект, указывающий на успешное соединение.
Чтобы уменьшить количество кода, связанного с подключением, мы поместили ES-клиент в глобальную статическую переменную, на которую можно напрямую ссылаться в других методах.
public static RestHighLevelClient esClient;
static {
esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("IP", 9200, "http")));
}
Примечание. Замените IP-адрес на IP-адрес компьютера или сервера, на котором вы установили ES.
1. Создайте новый класс CreateIndex и введите следующий код:
package ElasticSearch.ElasticSearch;
import java.io.IOException;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.junit.Test;
public class CreateIndex {
/**
* создаватьиндекс *
* @throws IOException
*/
@Test
public void createIndex() throws IOException {
CreateIndexRequest createIndexRequest = new CreateIndexRequest("user");
CreateIndexResponse indexResponse = EsClientTest.esClient.indices().create(createIndexRequest,RequestOptions.DEFAULT);
boolean acknowledged = indexResponse.isAcknowledged();
System.out.println("Состояние индекса:" + acknowledged);
}
}
2. Запустите код
3. Запросите через клиентский интерфейс ES запрос, чтобы подтвердить успешность создания индекса.
1. Создайте новый класс GetIndex и введите следующий код:
package ElasticSearch.ElasticSearch;
import java.io.IOException;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.junit.Test;
public class GetIndex {
/**
* Запрос информации об индексе
*
* @throws IOException
*/
@Test
public void getIndex() throws IOException {
GetIndexRequest getIndexRequest = new GetIndexRequest("user");
GetIndexResponse getIndexResponse = EsClientTest.esClient.indices().get(getIndexRequest,RequestOptions.DEFAULT);
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getSettings());
}
}
2. Запустите код
1. Создайте новый класс DeleteIndex и введите следующий код:
package ElasticSearch.ElasticSearch;
import java.io.IOException;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.junit.Test;
public class DeleteIndex {
/**
* Удалить индекс
*
* @throws IOException
*/
@Test
public void deleteIndex() throws IOException {
DeleteIndexRequest getIndexRequest = new DeleteIndexRequest("user");
AcknowledgedResponse delete = EsClientTest.esClient.indices().delete(getIndexRequest, RequestOptions.DEFAULT);
System.out.println("Статус удаления индекса:" + delete.isAcknowledged());
}
}
2. Запустите код
3. Запросите через клиентский интерфейс ES запрос, чтобы подтвердить успешное удаление индекса.
В реальном процессе разработки операции с документами выполняются чаще. Далее мы продемонстрируем API операций, связанных с документами ES.
1. Добавьте следующий код в класс EsClientTest для дальнейшего использования:
public static ObjectMapper objectMapper = new ObjectMapper();
2. Для объекта, используемого для тестирования, создайте новый класс User:
package ElasticSearch.ElasticSearch;
public class User {
private String name;
private String sex;
private Integer age;
private Integer salary;
public User() {
}
public User(String name, String sex, Integer age, Integer salary) {
this.name = name;
this.sex = sex;
this.age = age;
this.salary = salary;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
1. Создайте новый класс AddDoc и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
public class AddDoc {
/**
* Добавить данные
*
* @throws Exception
*/
@Test
public void add() throws Exception {
IndexRequest indexRequest = new IndexRequest();
indexRequest.index("user").id("1008");
User user = new User();
user.setName("Сан Эрнян");
user.setAge(23);
user.setSex("женщина");
user.setSalary(7000);
String userData = EsClientTest.objectMapper.writeValueAsString(user);
indexRequest.source(userData, XContentType.JSON);
// Вставить данные
IndexResponse response = EsClientTest.esClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
System.out.println(response.getResult());
EsClientTest.esClient.close();
}
}
2. Запустите код
3. Запросите и подтвердите, успешно ли добавлены данные через клиентский интерфейс ES.
1. Создайте новый класс UpdateDoc и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
public class UpdateDoc {
/**
* Изменить данные
*
* @throws Exception
*/
@Test
public void update() throws Exception {
UpdateRequest request = new UpdateRequest();
request.index("user").id("1008");
request.doc(XContentType.JSON, "name", «Доминатрикс»);
// Вставить данные
UpdateResponse response = EsClientTest.esClient.update(request, RequestOptions.DEFAULT);
System.out.println(response.getResult());
}
}
2. Запустите код
3. Запросите и подтвердите, были ли данные успешно изменены через клиентский интерфейс ES.
1. Создайте новый класс DeleteDoc и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.client.RequestOptions;
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.client.RequestOptions;
import org.junit.Test;
public class DeleteDoc {
/**
* удалить
*
* @throws Exception
*/
@Test
public void delete() throws Exception {
DeleteRequest request = new DeleteRequest();
request.index("user").id("1008");
// Вставить данные
DeleteResponse delete = EsClientTest.esClient.delete(request, RequestOptions.DEFAULT);
System.out.println(delete.getResult());
}
}
2. Запустите код
3. Запросите через интерфейс клиента ES запрос, чтобы подтвердить, были ли данные успешно удалены.
1. Создайте новый класс BatchInsertDoc и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
public class BatchInsertDoc {
/**
* Добавлять партиями
*
* @throws Exception
*/
@Test
public void batchInsert() throws Exception {
BulkRequest bulkRequest = new BulkRequest();
User user1 = new Пользователь("Гуань Юй", "мужской", 33, 5500);
String userData1 = EsClientTest.objectMapper.writeValueAsString(user1);
IndexRequest indexRequest1 = new IndexRequest().index("user").id("1002").source(userData1, XContentType.JSON);
bulkRequest.add(indexRequest1);
User user2 = new Пользователь("Хуан Чжун", "мужской", 50, 8000);
String userData2 = EsClientTest.objectMapper.writeValueAsString(user2);
IndexRequest indexRequest2 = new IndexRequest().index("user").id("1003").source(userData2, XContentType.JSON);
bulkRequest.add(indexRequest2);
User user3 = new Пользователь("Хуан Чжун2", "мужской", 49, 10000);
String userData3 = EsClientTest.objectMapper.writeValueAsString(user3);
IndexRequest indexRequest3 = new IndexRequest().index("user").id("1004").source(userData3, XContentType.JSON);
bulkRequest.add(indexRequest3);
User user4 = new Пользователь("Чжао Юнь", "мужской", 33, 12000);
String userData4 = EsClientTest.objectMapper.writeValueAsString(user4);
IndexRequest indexRequest4 = new IndexRequest().index("user").id("1005").source(userData4, XContentType.JSON);
bulkRequest.add(indexRequest4);
User user5 = new Пользователь("Ма Чао", "мужской", 38, 20000);
String userData5 = EsClientTest.objectMapper.writeValueAsString(user5);
IndexRequest indexRequest5 = new IndexRequest().index("user").id("1006").source(userData5, XContentType.JSON);
bulkRequest.add(indexRequest5);
User user6 = new Пользователь("Гуань Юй", "мужской", 41, 27000);
String userData6 = EsClientTest.objectMapper.writeValueAsString(user6);
IndexRequest indexRequest6 = new IndexRequest().index("user").id("1007").source(userData6, XContentType.JSON);
bulkRequest.add(indexRequest6);
BulkResponse bulkResponse = EsClientTest.esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulkResponse.status());
System.out.println(bulkResponse.getItems());
}
}
2. Запустите код
3. Запросите и подтвердите, добавляются ли данные пакетно через интерфейс клиента ES.
1. Создайте новый класс BatchDeleteDoc и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.client.RequestOptions;
import org.junit.Test;
public class BatchDeleteDoc {
/**
* партияудалить
*
* @throws Exception
*/
@Test
public void batchDelete() throws Exception {
BulkRequest bulkRequest = new BulkRequest();
DeleteRequest indexRequest1 = new DeleteRequest().index("user").id("1002");
DeleteRequest indexRequest2 = new DeleteRequest().index("user").id("1003");
DeleteRequest indexRequest3 = new DeleteRequest().index("user").id("1004");
DeleteRequest indexRequest4 = new DeleteRequest().index("user").id("1005");
DeleteRequest indexRequest5 = new DeleteRequest().index("user").id("1006");
DeleteRequest indexRequest6 = new DeleteRequest().index("user").id("1007");
bulkRequest.add(indexRequest1);
bulkRequest.add(indexRequest2);
bulkRequest.add(indexRequest3);
bulkRequest.add(indexRequest4);
bulkRequest.add(indexRequest5);
bulkRequest.add(indexRequest6);
BulkResponse bulkResponse = EsClientTest.esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulkResponse.status());
System.out.println(bulkResponse.getItems());
}
}
2. Запустите код
3. Запросите и подтвердите успешность пакетного удаления данных через интерфейс клиента ES.
Мы знаем, что самая мощная функция es — это поиск документов. Далее мы продемонстрируем работу общих API, связанных с запросом документов es.
1. Создайте новый класс SearchIndexAll и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class SearchIndexAll {
/**
* Запросить Все данные по определенному индексу
*
* @throws Exception
*/
@Test
public void searchIndexAll() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
// Индекс во всех запросах данных
SearchSourceBuilder query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
request.source(query);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
3. Запрос данных через клиентский интерфейс ES согласован.
Рассмотрите возможность использования его в сценариях, когда необходимо получить несколько фрагментов данных одновременно.
1. Создайте новый класс MultiGetDoc и введите следующий код:
package ElasticSearch.ElasticSearch;
import java.util.Iterator;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.client.RequestOptions;
import org.junit.Test;
public class MultiGetDoc {
/**
* Пакетный запрос нескольких фрагментов данных
*
* @throws Exception
*/
@Test
public void searchIndexAll() throws Exception {
MultiGetRequest multiGetRequest = new MultiGetRequest();
multiGetRequest.add("user","1002");
multiGetRequest.add("user","1003");
MultiGetResponse responses = EsClientTest.esClient.mget(multiGetRequest, RequestOptions.DEFAULT);
Iterator<MultiGetItemResponse> iterator = responses.iterator();while(iterator.hasNext())
{
MultiGetItemResponse next = iterator.next();
System.out.println(next.getResponse().getSourceAsString());
}
}
}
2. Запустите код
Запрос на основе пола чем-то похож на эффект, когда sex='female' в MySQL.
1. Создайте новый класс TermQueryDoc и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class TermQueryDoc {
//private static final SearchRequest request = null;
/**
* Точный запрос в зависимости от условий
*
* @throws Exception
*/
@Test
public void termQueryDoc() throws Exception {
SearchRequest request = new SearchRequest();
TermQueryBuilder ageQueryBuilder = QueryBuilders.termQuery("sex", "женский");
SearchSourceBuilder query = new SearchSourceBuilder().query(ageQueryBuilder);
request.source(query);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
Изучите использование from + size.
1. Создайте новый класс Paging и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class Paging {
/**
*Запрос страницы
*
* @throws Exception
*/
@Test
public void paging() throws Exception {
//Пейджинг данных запроса
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
// (Номер текущей страницы – 1)*Количество элементов данных, отображаемых на каждой странице.
sourceBuilder.from(0);//Начальная страница
sourceBuilder.size(3); // Сколько элементов на каждой странице?
request.source(sourceBuilder);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
// Закрыть ES-клиент
EsClientTest.esClient.close();
}
}
2. Запустите код
Аналогично запросу только некоторых полей определенной таблицы в MySQL.
1. Создайте новый класс SearchIndexAll и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
public class QuerySortByAge {
/**
* сортировать запрос
*
* @throws Exception
*/
@Test
public void querySortByAge() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
sourceBuilder.sort("age", SortOrder.ASC);
request.source(sourceBuilder);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
1. Создайте новый класс SearchIndexAll и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
public class QueryFilter {
/**
* Фильтровать запрос
*
* @throws Exception
*/
@Test
public void queryFilter() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
request.source(sourceBuilder);
String[] includes = { "name", "sex" };
String[] excludes = { "age" };
sourceBuilder.fetchSource(includes, excludes);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
es может комбинировать несколько условий для запроса, например mysql, и проверять использование BoolQuery следующим образом: Запрашивать пользователей, которые являются мужчинами с гендерной дилеммой и находятся в возрасте от 35 до 45 лет.
1. Создайте новый класс MultiConditionQuery и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class MultiConditionQuery {
/**
* Запрос с несколькими условиями
*
* @throws Exception
*/
@Test
public void multiConditionQuery() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("sex","мужской"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("возраст").lt(45).gt(35));
sourceBuilder.query(boolQueryBuilder);
request.source(sourceBuilder);
Ответ SearchResponse = EsClientTest.esClient.search(запрос, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
1. Создайте новый класс RangeQuery и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class RangeQuery {
/**
* запрос диапазона
*
* @throws Exception
*/
@Test
public void rangeQuery() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQueryBuilder =
QueryBuilders.rangeQuery("age").gte(35).lte(45);
sourceBuilder.query(rangeQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
1. Создайте новый класс LikeQuery и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class LikeQuery {
/**
* нечеткий запрос
*
* @throws Exception
*/
@Test
public void likeQuery() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name","Хуан Чжун").fuzziness(Fuzziness.ONE);
sourceBuilder.query(fuzzyQueryBuilder);
request.source(sourceBuilder);
Ответ SearchResponse = EsClientTest.esClient.search(запрос, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
При выполнении поиска по ключевым словам ключевые слова в искомом контенте будут отображаться разными цветами, что называется выделением. Например: Baidu выделит красный цвет при поиске по ключевому слову «ElasticSearch».
Реализация HTML-кода для просмотра выделенных данных с помощью инструментов разработчика:
ElasticSearch может устанавливать теги и стили для ключевых слов в запрашиваемом контенте, но вам нужно указать ElasticSearch, какие теги использовать для переноса выделенных ключевых слов. Конкретные шаги заключаются в следующем:
1. Создайте новый класс HighlightQuery и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.Test;
public class HighlightQuery {
/**
* Выделить запрос
*
* @throws Exception
*/
@Test
public void highLightQuery() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
TermQueryBuilder ageQueryBuilder = QueryBuilders.termQuery("age", 33);
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color='red'>");
highlightBuilder.postTags("</font>");
highlightBuilder.field("name");
sourceBuilder.highlighter(highlightBuilder);
sourceBuilder.query(ageQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
1. Создайте новый класс MultiMatchQuery и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class MultiMatchQuery {
/**
* Запрос с несколькими полями соответствует определенному ключевому слову
*
* @throws Exception
*/
@Test
public void multiMatchQuery() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder();
MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery("Хуан Чжун","name", "sex");
multiMatchQuery.operator(Operator.OR);
builder.query(multiMatchQuery);
request.source(builder);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
1. Создайте новый класс AggregationQuery и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class AggregationQuery {
/**
* Агрегационный запрос
*
* @throws Exception
*/
@Test
public void multiMatchQuery() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder();
AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");
builder.aggregation(aggregationBuilder);
request.source(builder);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
1. Создайте новый класс GroupQuery и введите следующий код:
package ElasticSearch.ElasticSearch;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
public class GroupQuery {
/**
* Групповой запрос
*
* @throws Exception
*/
@Test
public void groupQuery() throws Exception {
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder();
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");
builder.aggregation(aggregationBuilder);
request.source(builder);
SearchResponse response = EsClientTest.esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
}
}
2. Запустите код
es предоставляет сторонний SDK, который можно быстро интегрировать с Spring и SpringBoot. Далее в качестве примера будут использоваться данные Spring.
Spring-boot-starter-data-elasticsearch аналогичен другим методам jpa, связанным с Spring. Он инкапсулирует богатый интерфейс API. Клиентам нужно только наследовать предоставляемый им интерфейс, чтобы удобно использовать встроенный API.
1. Нажмите «Файл» — «Создать» — «Другое» в левом верхнем углу экрана Eclipse.
2. Выберите проект Maven и нажмите «Далее».
3. Выберите место хранения проекта и нажмите «Далее».
4. Выберите вариант, заканчивающийся быстрым запуском или веб-приложением, и нажмите «Далее».
5. Введите идентификатор группы и идентификатор артефакта. После заполнения автоматически будет создан столбец «Пакет». Это имя пакета в проекте. Нажмите «Готово».
6. Создание проекта завершено
Когда вы впервые создаете проект Springboot, после завершения создания проект будет отмечен красным крестиком (хотя это не влияет на работу).
Причина: скомпилированная версия maven по умолчанию не соответствует используемому jdk.
Решение: Выберите проект:щелкните правой кнопкой мыши–> Maven --> Update Project
Ни о чем не беспокойтесь, просто нажмите «ОК».
Решение завершено, и красный крестик исчезает.
1. Присоединитесь к платформе SpringBoot: откройте файл pom.xml.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.6.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>
Создайте папку ресурсов. Эта папка в основном используется для хранения ресурсов конфигурации. Если она уже существует при создании проекта, нет необходимости создавать ее вручную.
Это проект maven, который только что создал Хун Гэ. Из этого мы видим, что в проекте нет папки src/main/resources, в которой хранятся файлы конфигурации.
Решение:
1. Выберите проект, щелкните правой кнопкой мыши и выберите: Построить, как показано на рисунке. Path --> Configure Build Path
2. Выберите каталог src/main/java и нажмите «Добавить Floder».
3. Выберите основной и нажмите «Создать новый флодер» ниже.
4. Затем введите ресурсы и нажмите «Готово».
5. В это время в предыдущем интерфейсе будет папка ресурсов, затем нажмите «ОК».
6. На этом этапе вернитесь к интерфейсу более высокого уровня. В этот момент вы увидите, что.../src/main/resources создан. Продолжайте нажимать кнопку ОК, и интерфейс автоматически закроется.
7. Возвращаемся в проект, папка создана! Итак, проблема решена!
1. Во вновь созданном источник/основной/java/ресурсы/папка Щелкните правой кнопкой мыши—new—otherсоздаватьapplication.properties
# es IP
elasticsearch.host=127.0.0.1
# es порт
elasticsearch.port=9200
# Настройте уровень журнала и включите журнал отладки
logging.level.com.congge=debug
Этот класс сущностей представляет собой промежуточный уровень преобразования, который соединяет документы es и клиенты. Студенты, которые использовали jpa или mybatis-plus, должны быть знакомы с этим.
package springframework.springframework.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Document(indexName = "shopping", shards = 3, replicas = 1)
public class Product{
//Должен иметь идентификатор, здесьиз id является уникальным во всем миреизлоготип,Эквивалентно es в"_id"
@Id
private Long id;//Уникальная идентификация продукта
/**
* type : Тип данных поля
* analyzer : Тип токенизатора
* index : Индексировать ли (по умолчанию: true)
* Keyword : Фразы без сегментации слов
*/
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String заголовок;//название продукта
@Field(type = FieldType.Keyword)
private String категория;//имя категории
@Field(type = FieldType.Double)
private Double цена;//цена продукта
@Field(type = FieldType.Keyword, index = false)
private String изображения;//адрес изображения
public void setId(long l) {
// TODO Auto-generated method stub
}
public void setTitle(String string) {
// TODO Auto-generated method stub
}
public void setCategory(String string) {
// TODO Auto-generated method stub
}
public void setPrice(double d) {
// TODO Auto-generated method stub
}
public void setImages(String string) {
// TODO Auto-generated method stub
}
}
package springframework.springframework.dao;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import springframework.springframework.entity.Product;
@Repository
public interface ProductDao extends ElasticsearchRepository<Product, Long>{
}
package springframework.springframework.config;
import lombok.Data;
import springframework.springframework.AbstractElasticsearchConfiguration;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
//@PropertySource(value = "application.properties")
@Configuration
@Data
@ConfigurationProperties(prefix = "elasticsearch")
public class EsConfig extends AbstractElasticsearchConfiguration {
private String host ;
private Integer port ;
//Переопределить метод родительского класса
@Override
public RestHighLevelClient elasticsearchClient() {
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
return restHighLevelClient;
}
}
Далее протестируйте его через JUnit
1. Создайте новый тестовый класс EsIndexTest.
package springframework.springframework;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import springframework.springframework.entity.Product;
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsIndexTest {
//инъекция ElasticsearchRestTemplate
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
//создавать индекс и добавлять конфигурацию сопоставления
@Test
public void createIndex(){
//создавать индекс, инициализация системы автоматически создаст индекс
System.out.println("создаватьиндекс"); }
@Test
public void deleteIndex(){
//создавать индекс, инициализация системы автоматически создаст индекс
boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);
System.out.println("Удалить индекс = " + flg);
}
}
2. На основе метода Spring-данных при запуске проекта он автоматически считывает аннотации, относящиеся к классу сущности, автоматически завершает создание индекса и запускает тестовый метод для создания индекса.
3. Запросите и подтвердите, успешно ли созданы данные через клиентский интерфейс ES.
1. Создайте новый тестовый класс документа EsDocTest (в этом тестовом классе перечислены общие операции добавления, удаления, изменения и запроса).
package springframework.springframework;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
import springframework.springframework.dao.ProductDao;
import springframework.springframework.entity.Product;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsDocTest {
@Autowired
private ProductDao productDao;
/**
* Новый
*/
@Test
public void save() {
Product product = new Product();
product.setId(2L);
product.setTitle("ipad mini");
product.setCategory("ipad");
product.setPrice(1998.0);
product.setImages("http://ipad.jpg");
productDao.save(product);
}
//Исправлять
@Test
public void update(){
Product product = new Product();
product.setId(2L);
product.setTitle("iphone");
product.setCategory("mobile");
product.setPrice(6999.0);
product.setImages("http://www.phone.jpg");
productDao.save(product);
}
//в соответствии с id Запрос
@Test
public void findById(){
Product product = productDao.findById(2L).get();
System.out.println(product);
}
//Все по Запросу
@Test
public void findAll(){
Iterable<Product> products = productDao.findAll();
for (Product product : products) {
System.out.println(product);
}
}
//удалить
@Test
public void delete(){
Product product = new Product();
product.setId(2L);
productDao.delete(product);
}
//партия Новый
@Test
public void saveAll(){
List<Product> productList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Product product = new Product();
product.setId(Long.valueOf(i));
product.setTitle("iphone" + i);
product.setCategory("mobile");
product.setPrice(5999.0 + i);
product.setImages("http://www.phone.jpg");
productList.add(product);
}
productDao.saveAll(productList);
}
//Пейджинговый запрос
@Test
public void findByPageable(){
//Установить сортировку(Сортировать по,Прямой или обратный порядок?,сортироватьиз id)
Sort sort = Sort.by(Sort.Direction.DESC,"id");
int currentPage=0;//Текущая страница, первая страница начинается с 0 начинать, 1 Обозначает вторую страницу
int pageSize = 5;//Сколько элементов отображается на каждой странице?
//Устанавливаем пейджинг Запроса
PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
//Пейджинговый запрос
Page<Product> productPage = productDao.findAll(pageRequest);
for (Product Product : productPage.getContent()) {
System.out.println(Product);
}
}
/**
* term Запрос
* search(termQueryBuilder) Вызов метода поиска,параметр Запрособъект-строитель
*/
@Test
public void termQuery(){
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "iphone");
Iterable<Product> products = productDao.search(termQueryBuilder);
for (Product product : products) {
System.out.println(product);
}
}
/**
* term Запросдобавлять Пагинация
*/
@Test
public void termQueryByPage(){
int currentPage= 0 ;
int pageSize = 5;
//Устанавливаем пейджинг Запроса
PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "phone");
Iterable<Product> products =
productDao.search(termQueryBuilder,pageRequest);
for (Product product : products) {
System.out.println(product);
}
}
}
2. Проверьте метод добавления пакетов.
3. Запросите и подтвердите, добавляются ли данные пакетно через интерфейс клиента ES.
Студенты, которые заинтересованы в использовании более богатых интерфейсов API, могут продолжить углубленное обучение на основе Hongge.