SpringElasticsearch
Spring-Elasticsearch官方文档:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#reference
Spring Data Elasticsearch 在连接到单个 Elasticsearch 节点或集群的 Elasticsearch 客户端上运行。
尽管 Elasticsearch Client 可用于与集群一起工作,但使用 Spring Data Elasticsearch 的应用程序通常使用 Elasticsearch Operations and Elasticsearch Repositories 的更高级别抽象
Spring-data-elasticsearch依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version>2.6.2</version> </dependency>
一、客户端
Spring官方强烈建议使用使用 High Level REST Client 而不是 TransportClient,TransportClient 自 Elasticsearch 7 起已弃用,并将在 Elasticsearch 8 中删除
1、TransportClient(弃用)
@Configuration public class TransportClientConfig extends ElasticsearchConfigurationSupport { @Bean public Client elasticsearchClient() throws UnknownHostException { // 必须使用集群名称配置 TransportClient。 Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings); // 连接客户端的主机和端口。 client.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); return client; } @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException { ElasticsearchTemplate template = new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter); // RefreshPolicy 必须在 ElasticsearchTemplate 中设置(覆盖 refreshPolicy() 以不使用默认值) template.setRefreshPolicy(refreshPolicy()); return template; } } // 使用 IndexRequest request = new IndexRequest("spring-data") .id(randomID()) .source(someObject); IndexResponse response = client.index(request);
2、 High Level REST Client(高级REST客户端,推荐使用,目前也已经弃用)
Java High Level REST Client 是 Elasticsearch 的默认客户端,它提供了对 TransportClient 的直接替代,因为它接受并返回完全相同的请求/响应对象,因此依赖于 Elasticsearch 核心项目。异步调用在客户端管理的线程池上进行操作,并且需要在请求完成时通知回调
1)配置
@Configuration public class RestClientConfig extends AbstractElasticsearchConfiguration { @Override @Bean public RestHighLevelClient elasticsearchClient() { // 使用构建器提供集群地址、设置默认 HttpHeaders 或启用 SSL final ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .build(); // 创建高级REST客户端并返回 return RestClients.create(clientConfiguration).rest(); } }
2)使用
@Autowired RestHighLevelClient highLevelClient; RestClient lowLevelClient = highLevelClient.lowLevelClient(); // ... IndexRequest request = new IndexRequest("spring-data") .id(randomID()) .source(singletonMap("feature", "high-level-rest-client")) .setRefreshPolicy(IMMEDIATE); IndexResponse response = highLevelClient.index(request,RequestOptions.DEFAULT);
3、 Reactive Client
ReactiveElasticsearchClient 是一个基于 WebClient 的非官方驱动。它使用 Elasticsearch 核心项目提供的请求/响应对象。调用直接在响应式堆栈上操作,而不是将异步(线程池绑定)响应包装到响应式类型中。
@Configuration public class ReactiveRestClientConfig extends AbstractReactiveElasticsearchConfiguration { @Override @Bean public ReactiveElasticsearchClient reactiveElasticsearchClient() { // 使用构建器提供集群地址、设置默认 HttpHeaders 或启用 SSL final ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") // .build(); return ReactiveRestClients.create(clientConfiguration); } } // ... Mono<IndexResponse> response = client.index(request -> request.index("spring-data") .id(randomID()) .source(singletonMap("feature", "reactive-client")); );
二、客户端配置
客户端行为可以通过允许设置 SSL 选项、连接和套接字超时、标头和其他参数的 ClientConfiguration 进行更改
HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add("some-header", "on every request") ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200", "localhost:9291") // 使用构建器提供集群地址、设置默认 HttpHeaders 或启用 SSL。 .usingSsl() // 可选择启用 SSL .withProxy("localhost:8888") // (可选)设置代理 .withPathPrefix("ela") // 可选地设置路径前缀,主要用于在某些反向代理后面的不同集群时 .withConnectTimeout(Duration.ofSeconds(5)) // 设置连接超时,默认是10秒 .withSocketTimeout(Duration.ofSeconds(3)) // 设置socket超时,默认是5秒 .withDefaultHeaders(defaultHeaders) // 可选地设置header .withBasicAuth(username, password) // 添加基本身份验证 .withHeaders(() -> { // 可以指定一个 Supplier<Header> 函数,每次在请求发送到 Elasticsearch 之前都会调用该函数 - 例如,当前时间被写入header中 HttpHeaders headers = new HttpHeaders(); headers.add("currentTime", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); return headers; }) .withClientConfigurer( // 用于响应式设置配置 WebClient 的功能 ReactiveRestClients.WebClientConfigurationCallback.from(webClient -> { // ... return webClient; })) .withClientConfigurer( // 对于非反应式设置,配置 REST 客户端的功能 RestClients.RestClientConfigurationCallback.from(clientBuilder -> { // ... return clientBuilder; })) . // ... other options .build();
客户端日志:
要查看实际发送到服务器和从服务器接收的内容,需要打开传输级别的请求/响应日志记录,如:
<logger name="org.springframework.data.elasticsearch.client.WIRE" level="trace"/>
三、Elasticsearch对象映射
Spring Data Elasticsearch对象映射是将一个Java对象(域实体)映射为存储在Elasticsearch中的JSON文档
映射注释:
@Document:在实体类上使用,用来指示该类是映射到数据库候选对象,有如下属性:
indexName:存储此实体的索引的名称。
createIndex:标记是否创建索引,默认为true
versionType:版本管理的配置,默认为EXTERNAL
@Id:用来将对象中id和ES中_id映射
@Transient:默认情况下,所有字段在存储或检索时都映射到文档,此注释不包括该字段
@PersistenceConstructor:标记一个给定的构造函数,可以是一个包保护的构造函数。在从数据库实例化对象时使用,构造函数按名称映射到检索到的Document中的键值
@Field:应用于字段级别并定义字段的属性,此注解有如下属性:
name:Elasticsearch 文档中表示的字段名称,如果未设置,则使用 Java 字段名称
type:字段类型,可以是Text、Keyword、Long、Integer、Short、Byte、Double、Float、Half_Float、Scaled_Float、Date、Date_Nanos、Boolean、Binary、Integer_Range、Float_Range、Long_Range、Double_Range、Date_Range、Ip_Range、Object 之一, 嵌套, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type。
如果未指定字段类型,则默认为FieldType.Auto,这意味着,不会为该属性不会为该属性写入任何映射条目,并且 Elasticsearch 将在存储该属性的第一个数据时动态添加一个映射条目
format:一种或多种内置日期格式 日期格式映射
pattern:一种或多种自定义日期格式 日期格式映射
store:标记原始字段值是否应该存储在 Elasticsearch 中,默认值为false
analyer、searchAnalyzer、normalizer:用于指定自定义分析器和规范器
日期格式映射:
annotation | format string in Elasticsearch mapping |
---|---|
@Field(type=FieldType.Date) |
"date_optional_time||epoch_millis", |
@Field(type=FieldType.Date, format=DateFormat.basic_date) |
"basic_date" |
@Field(type=FieldType.Date, format={DateFormat.basic_date, DateFormat.basic_time}) |
"basic_date||basic_time" |
@Field(type=FieldType.Date, pattern="dd.MM.uuuu") |
"date_optional_time||epoch_millis||dd.MM.uuuu", |
@Field(type=FieldType.Date, format={}, pattern="dd.MM.uuuu") |
"dd.MM.uuuu" |
四、Elasticsearch操作
Spring Data Elasticsearch 使用多个接口来定义可以针对 Elasticsearch 索引调用的操作
IndexOperations:定义索引级别的操作,例如创建或删除索引
DocumentOperations:定义操作以根据实体 ID 存储、更新和检索实体
SearchOperations:定义使用查询搜索多个实体的操作
ElasticsearchOperations:结合了 DocumentOperations 和 SearchOperations 接口
1、ElasticsearchTemplate
自 4.0 版起,不推荐使用 ElasticsearchTemplate,请改用 ElasticsearchRestTemplate
ElasticsearchTemplate 是使用Transport Client的 ElasticsearchOperations 接口的实现
2、ElasticsearchRestTemplate
ElasticsearchRestTemplate 是使用高级 REST 客户端的 ElasticsearchOperations 接口的实现
ElasticsearchRestTemplate配置:
@Configuration public class RestClientConfig extends AbstractElasticsearchConfiguration { @Override public RestHighLevelClient elasticsearchClient() { // 设置高级 REST 客户端 return RestClients.create(ClientConfiguration.localhost()).rest(); } // no special bean creation needed
// 基类 AbstractElasticsearchConfiguration 已经提供了 elasticsearchTemplate bean }
操作示例:
由于 ElasticsearchTemplate 和 ElasticsearchRestTemplate 都实现了 ElasticsearchOperations 接口,因此使用它们的代码没有什么不同。该示例展示了如何在 Spring REST controller中使用注入的 ElasticsearchOperations 实例。
根据我们的配置决定使用TransportClient 或 RestClient
import com.yang.custom.es.model.Employee; import org.elasticsearch.index.query.QueryBuilders; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("es") public class EsSearchController { /** * ElasticsearchTemplate 和 ElasticsearchRestTemplate 都实现了 ElasticsearchOperations 接口 * Spring根据配置注入ElasticsearchTemplate或ElasticsearchRestTemplate */ private ElasticsearchOperations elasticsearchOperations; /** * 构造器注入ElasticsearchOperations bean * * @param elasticsearchOperations */ public EsSearchController(ElasticsearchOperations elasticsearchOperations) { this.elasticsearchOperations = elasticsearchOperations; } /** * 根据条件查询文档数据 * * @return */ @GetMapping("query") public List<Employee> queryEmployees() { // 构造查询条件,查询索引中last_name属性值为Smith的文档 NativeSearchQuery nativeQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("last_name", "Smith")) .build(); // 查询 SearchHits<Employee> searchHits = elasticsearchOperations.search(nativeQuery, Employee.class); List<SearchHit<Employee>> searchHitList = searchHits.getSearchHits(); List<Employee> employees = new ArrayList<>(); for (SearchHit<Employee> searchHit : searchHitList) { Employee employee = searchHit.getContent(); employees.add(employee); } return employees; } /** * 插入文档到索引 */ @PutMapping public void insertEmployee() { Employee employee = new Employee(); employee.setFirstName("yang"); employee.setLastName("yongjie"); employee.setAge(26); employee.setAbout("badminton"); elasticsearchOperations.save(employee); } }
Employee实体:
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import java.util.List; @Document(indexName = "megacorp") public class Employee { @Field(name = "first_name", type = FieldType.Text) private String firstName; @Field(name = "last_name", type = FieldType.Text) private String lastName; @Field(type = FieldType.Integer) private Integer age; @Field(type = FieldType.Text) private String about; private List<String> interests; // getter and setter ... }
Bulk操作
批量请求允许在一个请求中向 Elasticsearch 发送多个与文档相关的操作。当您有多个文档要摄取时,这比使用单独的请求发送每个文档更有效
Bulk请求可以包含以下几种操作:
create:创建一个文档,在确保它不存在后对其进行索引
index:索引文档,在需要时创建它,如果存在则替换它(注意:替换不是更新)
update:更新一个已经存在的文档,可以是一个脚本,也可以是一个部分文档
delete:删除一个文档
// BulkRequest 建造器
BulkRequest.Builder br = new BulkRequest.Builder();
br.operations(op -> op
.index(idx -> idx
.index("products")
.id(product.getSku())
.document(product)
)
);
br.operations(new BulkOperation.Builder().create().build());
br.operations(new BulkOperation.Builder().index().build());
br.operations(new BulkOperation.Builder().update().build());
br.operations(new BulkOperation.Builder().delete().build());
//
BulkResponse result = elasticsearchClient.bulk(br.build());
RESTful示例:
curl -X POST "localhost:9200/_bulk?pretty" -H 'Content-Type: application/json' -d'
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }
'
Python:
resp = client.bulk(
body=[
{"index": {"_index": "test", "_id": "1"}},
{"field1": "value1"},
{"delete": {"_index": "test", "_id": "2"}},
{"create": {"_index": "test", "_id": "3"}},
{"field1": "value3"},
{"update": {"_id": "1", "_index": "test"}},
{"doc": {"field2": "value2"}},
],
)
print(resp)
注意:update json数据前要加 doc
Bulk文档:https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/indexing-bulk.html
以上为Spring集成的Elasticsearch客户端的使用,下面是原生的Java API Client
五、Elasticsearch Java API Client
1、依赖
<dependencies> <dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>8.1.2</version> </dependency>
<!-- spring框架会依赖,不必添加 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.3</version> </dependency> </dependencies>
依据官方文档,如果出现了 ClassNotFoundException: jakarta.json.spi.JsonProvider 异常,则添加以下依赖:
<!-- Needed only if you use the spring-boot Maven plugin -->
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.0.1</version>
</dependency>
注意:在多模块项目中,如果在common模块中添加此依赖,仍会报上面异常。将elasticsearch-java依赖在common模块中配置,将jakarta.json-api在顶级启动模块中配置即可。
2、连接
Java API 客户端围绕三个主要组件构建:
①:API 客户端类。它们为 Elasticsearch API 提供强类型数据结构和方法。由于 Elasticsearch API 很大,它以功能组(也称为“命名空间”)的形式进行结构化,每个功能组都有自己的客户端类。Elasticsearch 核心功能在ElasticsearchClient类中实现。
②:JSON 对象映射器。这会将您的应用程序类映射到 JSON 并将它们与 API 客户端无缝集成。
③:传输层实现。这是所有 HTTP 请求处理发生的地方
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* es客户端配置
*
* @author yangyongjie
* @date 2022/10/17
*/
@Configuration
public class EsRestClientConfig {
@Bean
public ElasticsearchClient esClient() {
// 身份认证
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user", "test-user-password"));
// 创建低级客户端
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
})
.build();
//使用 Jackson 映射器创建传输
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
// 创建低级客户端
ElasticsearchClient client = new ElasticsearchClient(transport);
return client;
}
}
3、索引操作
①:添加索引
CreateIndexResponse response = elasticsearchClient.indices().create(new CreateIndexRequest.Builder() .index(appIndexName) .settings(new IndexSettings.Builder() .numberOfShards("3") // 三个分片 .numberOfReplicas("1") // 每个分片一个副本 .build()) .aliases("appstore_app_info", new Alias.Builder(). isWriteIndex(true) .build()) .build()); String index = response.index();
②:删除索引
DeleteIndexResponse deleteIndexResponse = elasticsearchClient.indices().delete(new DeleteIndexRequest.Builder() .index(appIndexName) .build());
4、文档操作
①:搜索
SearchResponse<AppInfo> response = elasticsearchClient.search(new SearchRequest.Builder()
.index(appIndexName)
.query(new Query.Builder()
// match_phrase搜索
.matchPhrase(new MatchPhraseQuery.Builder()
.field("app_name.pinyin")
.query("sc")
.build())
// wildcard搜索
// .wildcard(new WildcardQuery.Builder()
// .field("traceId")
// .value("*htmn")
// .build())
// match搜索
// .match(new MatchQuery.Builder()
// .field("app_name")
// .query("hello")
// .build())
// term搜索
// .term(new TermQuery.Builder()
// .field("app_name")
// .value(new FieldValue.Builder().stringValue("视频头条").build())
// .build())
.build())
// 分页
.from(10)
.size(10)
.build(),
AppInfo.class);
term搜索:
GET index_name/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"field1": "value1"
}
},
{
"term": {
"field2": "value2"
}
}
]
}
}
}
SearchResponse<Map> response = elasticsearchClient.search(new SearchRequest.Builder()
.index("index_name")
.query(new Query.Builder()
.bool(new BoolQuery.Builder()
.must(new Query.Builder()
// term搜索
.term(new TermQuery.Builder()
.field("field1")
.value(new FieldValue.Builder().stringValue("value1").build())
.build())
.build(),
new Query.Builder()
// term搜索
.term(new TermQuery.Builder()
.field("field2")
.value(new FieldValue.Builder().stringValue("value2").build())
.build())
.build()
)
.build())
.build())
.build(),
Map.class);
terms搜索:
List<FieldValue> fieldValues=new ArrayList<>();
fieldValues.add(new FieldValue.Builder().stringValue("视频头条").build());
fieldValues.add(new FieldValue.Builder().stringValue("电视商城").build());
// 索引
searchRequestBuilder.index(indexName)
.query(new Query.Builder()
.terms(new TermsQuery.Builder()
.field("app_name")
.terms(new TermsQueryField.Builder().value(fieldValues).build())
.build())
.build())
// 分页
.from(traceLogQuery.getFrom())
.size(traceLogQuery.getSize());
②:写文档
long id = 12L; AppInfo appInfo = new AppInfo(); appInfo.setId(id); appInfo.setAppName("电视商店"); appInfo.setUpdateTime(new Date()); CreateResponse createResponse = esClient.create(new CreateRequest.Builder<AppInfo>() .id(String.valueOf(id)) // 对应_id,建议设设置值与doc中的id值一致 .index("mib_tv_appstore_app_info") .document(appInfo) .build());
③:更新
AppInfo appInfo = new AppInfo(); appInfo.setApp_name("电视商城"); appInfo.setIs_default_recommend(CommonConstant.STR_ONE); appInfo.setIs_online(CommonConstant.STR_ONE); UpdateResponse<AppInfo> updateResponse = elasticsearchClient.update(new UpdateRequest.Builder<AppInfo, AppInfo>() .index(appIndexName) .id("1") .doc(appInfo) .docAsUpsert(true) // 如果文档不存在,则插入新文档 .build(), AppInfo.class);
④:删除
/*// 查询并删除 elasticsearchClient.deleteByQuery(new DeleteByQueryRequest.Builder() .index(appIndexName) .query(new Query.Builder() .match(new MatchQuery.Builder() .field("app_name") .query("hello elasticsearch") .build()) .build()) .build());*/ // 根据id删除 DeleteResponse deleteResponse = elasticsearchClient.delete(new DeleteRequest.Builder() .index(appIndexName) .id("1") .build());
⑤:根据id获取文档
GetResponse<AppInfo> getResponse = elasticsearchClient.get(new GetRequest.Builder() .index(appIndexName) .id(String.valueOf(id)) .build(), AppInfo.class); // 是否找到,即id的文档是否存在 boolean found = getResponse.found(); AppInfo appInfo = getResponse.source();
⑥:upset,存在更新,不存在插入
UpdateRequest updateRequest=new UpdateRequest.Builder<Map, Map>()
.index(index)
.id(oneId)
.doc(mediaMap)
.docAsUpsert(true) //不存在则插入
.build();
// 更新es
elasticsearchClient.update(updateRequest, Map.class);
HTTP方式:
1、依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.9</version>
</dependency>
2、配置RestHighLevelClient
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Elasticsearch 配置类
*/
@Configuration
public class ElasticSearchConfig {
@Value("${es.knowledge.url}")
private String serverUri;
@Value("${es.knowledge.username}")
private String knowledgeUserName;
@Value("${es.knowledge.access1}")
private String knowledgePassword;
@Bean(destroyMethod = "close")
public RestHighLevelClient esRestHighLevelClient() {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(knowledgeUserName, knowledgePassword));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(
new HttpHost(HttpHost.create(serverUri))
).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
})
);
return restHighLevelClient;
}
}
3、操作
@Resource(name = "esRestHighLevelClient")
private RestHighLevelClient esRestHighLevelClient;
@Test
void restHighLevelClientTest() throws IOException {
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termsQuery("metaId", "103249"));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = esRestHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits=searchResponse.getHits();
}
Jest客户端
Jest是一个ElasticSearch Java HTTP Rest 客户端(18年之后不再维护,对新版es不能支持)
1、添加依赖
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>6.3.1</version>
</dependency>
2、创建JestClient实例
注意:JavaClient 设计为单例的,不必为每个请求都创建
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.config.HttpClientConfig;
import org.springframework.context.annotation.Configuration;
/**
* Elasticsearch Jest客户端
*
* @author yangyongjie
*/
@Configuration
public class ElasticSearchJestConfig {
@Bean
public JestClient jestClient() {
// 根据JestClientFactory创建一个Jest客户端
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig
.Builder("http://localhost:9200")
.defaultCredentials("username", "password")
.multiThreaded(true)
// 每个路由绑定最大连接数,默认不超过2个
.defaultMaxTotalConnectionPerRoute(2)
// 最大连接数
.maxTotalConnection(20)
.build());
JestClient client = factory.getObject();
return client;
}
}
3、操作示例
@Resource
private JestClient jestClient;
@Test
public void jestClientTest() throws IOException {
String query = "{\n" +
" \"query\": {\n" +
" \"term\": {\n" +
" \"metaId\": {\n" +
" \"value\": \"103249\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
Search search = new Search.Builder(query)
// multiple index or types can be added.
.addIndex("tv_knowledge_movie_update_calendar_staging")
.build();
SearchResult result = jestClient.execute(search);
System.out.println(result);
}
附录:
ES客户端文档:https://www.elastic.co/guide/en/elasticsearch/client/index.html
Jest客户端:https://github.com/searchbox-io/Jest/blob/master/jest/README.md#comparison-to-native-api
END.