内容简介:包括TransportClient、Low Level Rest Client、High Level Rest Cliet的详细用法,此外还包括高亮搜索、聚合搜索、SQL搜索、SpringDataElasticSearch的Template搜索,Repositories搜索等;涵盖Java操作ElasticSearch的所有API!
一、ElasticSearch Java API
ElasticSearch官方支持当下几乎所有流行编程语言,如Java、JavaScript、Ruby、Go、.Net、Python等。并且在ElasticSearch官方中都有非常详细的使用案例介绍:
ElasticSearch的客户端工具官方文档:https://www.elastic.co/guide/en/elasticsearch/client/index.html
在使用Java客户端操作ElasticSearch时,官方提供有Java Transport Client 和Java REST Client 方式;其中Java REST Client 分为Java Low Level REST Client 和Java High Level REST Client 两种方式;
Java Transport Client :ES的早期连接工具,TransportClient通过TCP方式访问ES,功能强大,上手简单,ElasticSearch早期推出的Java客户端工具;在7.0版本中不再建议使用,将会在8.0版本中被删除;Java REST Client :5.0版本新推出的Java客户端工具,RestClient方式通过http访问ES,依赖于JDK1.8(官方推荐);
Java Low Level REST Client :官方的低级客户端。它允许通过http 与一个Elasticsearch 集群通信。将请求的编组和响应的反编组工作留给用户自己处理。它兼容所有的Elasticsearch 的版本。Java High Level REST Client :官方的高级客户端。它基于低级客户端,它暴露了API 特定的方法,并负责处理请求编组和响应非编组。
Tips:需要注意的是:TransportClient的默认端口是9300,而Rest Client的默认端口是9200
官方参考资料:
1.1 搭建环境
1.1.1 Maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<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>com.es</groupId>
<artifactId>01_ElasticSearch_API</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.6.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>7.6.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1.1.2 实体类
package com.es.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Goods {
private String id;
private String name;
private String title;
private Double price;
private String[] category;
}
1.1.3 建立连接
package com.es.demo;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;
public class Demo01_ES_Connection {
@Test
public void test1() throws Exception {
Settings settings = Settings.builder().put("cluster.name", "my-cluster").build();
TransportClient client = new PreBuiltTransportClient(settings);
System.out.println(client);
client.close();
}
@Test
public void test2() throws Exception {
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200, "http")
).build();
System.out.println(restClient);
}
@Test
public void test3() throws Exception {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")
)
);
System.out.println(client);
}
}
1.2 TransportClient 的用法
-
1)TransportClient 使用9300端口远程连接到 Elasticsearch 集群,客户端并不加入集群,而是通过获取单个或者多个transport地址来以轮询的方式与他们通信。 -
2)TransportClient使用传输协议与Elasticsearch节点通信,如果客户端的版本和与其通信的ES实例的版本不同,就会出现兼容性问题。而low-level REST使用的是HTTP协议,可以与任意版本ES集群通信。high-level REST是基于low-level REST的。
ElasticSearch官方关于TransportClient的使用方法:https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.6/index.html
1.2.1 索引相关
TransportClient 索引相关API:https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.6/java-admin-indices.html
要进行索引的管理必须获取到IndicesAdminClient 对象来进行索引管理:
AdminClient adminClient = transportClient.admin();
IndicesAdminClient indices = adminClient.indices();
1)prepareXxx相关方法
package com.es.demo;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.util.Arrays;
public class Demo02_Index_TransportClient_Prepare {
private Settings settings;
private TransportClient client;
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "elasticsearch").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void test1() throws Exception {
AdminClient adminClient = client.admin();
IndicesAdminClient indices = adminClient.indices();
indices.prepareCreate("goodsindex")
.setSettings(
Settings.builder()
.put("index.number_of_shards", 3)
.put("index.number_of_replicas", 1)
).get();
}
@Test
public void test2() throws Exception {
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.startObject("_doc")
.startObject("properties")
.startObject("id")
.field("type", "integer")
.field("store", "true")
.endObject()
.startObject("name")
.field("type", "text").field("store", "true").field("analyzer", "standard")
.endObject()
.startObject("title")
.field("type", "text").field("store", "true").field("analyzer", "standard")
.endObject()
.startObject("price")
.field("type", "double")
.endObject()
.startObject("category")
.field("type", "text").field("fielddata", true)
.endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest mapping = Requests.putMappingRequest("goodsindex")
.type("_doc").source(builder);
IndicesAdminClient indices = client.admin().indices();
indices.putMapping(mapping).get();
}
@Test
public void test3() throws Exception {
IndicesAdminClient indices = client.admin().indices();
indices.prepareDelete("goodsindex").get();
}
@Test
public void test4() throws Exception {
IndicesAdminClient indices = client.admin().indices();
indices.prepareUpdateSettings("goodsindex")
.setSettings(
Settings.builder().put("index.number_of_replicas", 1)
).get();
}
@Test
public void test5() throws Exception {
IndicesAdminClient indices = client.admin().indices();
GetIndexResponse indexResponse = indices.prepareGetIndex().get();
String[] indexNames = indexResponse.getIndices();
System.out.println("indexNames: " + Arrays.toString(indexNames));
}
@Test
public void test6() throws Exception {
IndicesAdminClient indices = client.admin().indices();
GetSettingsResponse response = indices.prepareGetSettings("goodsindex").get();
for (ObjectObjectCursor<String, Settings> cursor : response.getIndexToSettings()) {
String index = cursor.key;
Settings settings = cursor.value;
Integer shards = settings.getAsInt("index.number_of_shards", null);
Integer replicas = settings.getAsInt("index.number_of_replicas", null);
System.out.println("index: " + index);
System.out.println("settings: " + settings);
System.out.println("shards: " + shards);
System.out.println("replicas: " + replicas);
}
}
}
2)封装Request相关方法
package com.es.demo;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.util.HashMap;
public class Demo03_Index_TransportClient {
private Settings settings;
private TransportClient client;
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "elasticsearch").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void test1() throws Exception {
AdminClient adminClient = client.admin();
IndicesAdminClient indices = adminClient.indices();
CreateIndexRequest createIndexRequest = new CreateIndexRequest("goodsindex");
createIndexRequest.settings(
Settings.builder()
.put("index.number_of_shards", 3)
.put("index.number_of_replicas", 2)
);
indices.create(createIndexRequest).get();
}
@Test
public void test2() throws Exception {
IndicesAdminClient indices = client.admin().indices();
indices.delete(new DeleteIndexRequest("goodsindex")).get();
}
@Test
public void test3() throws Exception {
IndicesAdminClient indices = client.admin().indices();
UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest();
HashMap<String, Object> settingsParams = new HashMap<>();
settingsParams.put("index.number_of_replicas", 1);
updateSettingsRequest.settings(settingsParams);
indices.updateSettings(updateSettingsRequest).get();
}
@Test
public void test4() throws Exception {
IndicesAdminClient indices = client.admin().indices();
GetIndexRequest getIndexRequest = new GetIndexRequest();
GetIndexResponse indexResponse = indices.getIndex(getIndexRequest).get();
String[] indexNames = indexResponse.getIndices();
System.out.println("indexNames: " + indexNames);
}
}
1.2.2 文档相关
TransportClient文档管理相关API:https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.6/index.html
同样,对于文档管理相关功能的API在ElasticSearch官网中提供有两种方式:
- 1)prepareXxx相关方法:
prepareIndex :创建文档prepareDelete :删除文档prepareUpdate :修改文档prepareGet :查询文档 - 2)直接功能方法:
- index:创建文档
- delete:删除文档
- update:修改文档
- get:查询文档
1)preapeXxx相关方法
package com.es.demo;
import com.es.entity.Goods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.util.Map;
public class Demo04_Document_TransportClient_Prepare {
private Settings settings;
private TransportClient client;
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "elasticsearch").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void test1() throws Exception {
Goods goods = new Goods("1",
"xiaomi shouji",
"xiaomi 5G paizhao shouji",
2899.0D,
new String[]{"5G", "paizhao"}
);
ObjectMapper objectMapper = new ObjectMapper();
String goodsJson = objectMapper.writeValueAsString(goods);
client.prepareIndex("goodsindex", "_doc", "1").setSource(goodsJson, XContentType.JSON).get();
}
@Test
public void test2() throws Exception {
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.field("id", "2")
.field("name", "huawei shouji")
.field("title", "huawei 4G youxi shouji")
.field("price", 988)
.field("category", new String[]{"4G", "youxi"})
.endObject();
client.prepareIndex("goodsindex", "_doc", "2").setSource(builder).get();
}
@Test
public void test3() throws Exception {
client.prepareDelete("goodsindex", "_doc", "1").get();
}
@Test
public void test4() throws Exception {
Goods goods = new Goods("2",
"lianxian shouji",
"lianxiang 5G youxi shouji",
3899.0D,
new String[]{"5G", "youxi"}
);
ObjectMapper om = new ObjectMapper();
String goodsJson = om.writeValueAsString(goods);
client.prepareUpdate("goodsindex", "_doc", "2").setDoc(goodsJson, XContentType.JSON).get();
}
@Test
public void test5() throws Exception {
GetResponse response = client.prepareGet("goodsindex", "_doc", "1").get();
Map<String, Object> sourceAsMap = response.getSourceAsMap();
System.out.println("map: " + sourceAsMap);
String jsonStr = response.getSourceAsString();
System.out.println("jsonStr: " + jsonStr);
}
}
2)封装Request相关方法
package com.es.demo;
import com.es.entity.Goods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.util.Map;
public class Demo05_Document_TransportClient {
private Settings settings;
private TransportClient client;
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "elasticsearch").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void test1() throws Exception {
Goods goods = new Goods("1",
"xiaomi shouji",
"xiaomi 5G paizhao shouji",
2899.0D,
new String[]{"5G", "paizhao"}
);
ObjectMapper objectMapper = new ObjectMapper();
String goodsJson = objectMapper.writeValueAsString(goods);
IndexRequest indexRequest = new IndexRequest("goodsindex", "_doc", "1");
indexRequest.source(goodsJson, XContentType.JSON);
client.index(indexRequest).get();
}
@Test
public void test2() throws Exception {
client.delete(new DeleteRequest("goodsindex", "_doc", "1")).get();
}
@Test
public void test3() throws Exception {
UpdateRequest updateRequest = new UpdateRequest("goodsindex", "_doc", "2");
Goods goods = new Goods("1",
"lianxian shouji",
"lianxiang 5G youxi shouji",
3899.0D,
new String[]{"5G", "youxi"}
);
ObjectMapper om = new ObjectMapper();
updateRequest.doc(om.writeValueAsString(goods), XContentType.JSON);
client.update(updateRequest).get();
}
@Test
public void test4() throws Exception {
GetRequest getRequest = new GetRequest("goodsindex", "_doc", "2");
GetResponse res = client.get(getRequest).get();
Map<String, Object> goodsMap = res.getSource();
System.out.println(goodsMap);
String goodsJson = res.getSourceAsString();
System.out.println(goodsJson);
}
}
1.2.3 搜索相关功能
DELETE goodsindex
POST /goodsindex/_doc/1
{
"name":"huawei shouji",
"title":"huawei 4G quanmianping youxi shouji",
"price":4899,
"category":["youxi","4G","quanmianping"]
}
POST /goodsindex/_doc/2
{
"name":"vivo shouji",
"title":"vivo 5G paizhao shouji",
"price":2899,
"category":["5G","paizhao"]
}
POST /goodsindex/_doc/3
{
"name":"oppo shouji",
"title":"oppo 5G paizhao shouji",
"price":1899,
"category":["5G","paizhao"]
}
POST /goodsindex/_doc/4
{
"name":"huawei shouji",
"title":"huawei 5G youxi shouji",
"price":3899,
"category":["5G","youxi"]
}
POST /goodsindex/_doc/5
{
"name":"xiaomi shouji",
"title":"xiaomi 4G youxi shouji",
"price":988,
"category":["youxi","4G"]
}
POST /goodsindex/_doc/6
{
"name":"xiaomi shouji",
"title":"xiaomi 5G youxi qumianping shouji",
"price":1899,
"category":["youxi","5G","qumianping"]
}
POST /goodsindex/_doc/7
{
"name":"xiaomi shouji",
"title":"xiaomi 5G youxi shouji",
"price":1299,
"category":["youxi","5G"]
}
POST /goodsindex/_doc/8
{
"name":"xiaomi shouji",
"title":"xiaomi 4G shouji",
"price":869,
"category":["4G"]
}
POST /goodsindex/_doc/9
{
"name":"huawei shouji",
"title":"huawei 5G zhineng qumianping shouji",
"price":2899,
"category":["zhineng","5G","qumianping"]
}
POST /goodsindex/_doc/10
{
"name":"youxi shouji",
"title":"xiaomi 5G shouji",
"price":2899,
"category":["youxi","5G"]
}
1)SearchRequest搜索
-
SearchRequest :是ES提供的一个专门用于搜索的对象;在创建SearchRequest对象时指定要操作的索引(默认情况下在所有索引中搜索),SearchRequest可以执行封装大部分的搜索;例如string search 、queryDSL 、query filter 、phrase search 、term query 、query string 、highlight search 、聚合搜索 等; -
SearchSourceBuilder :搜索源构建对象,在此对象中设置搜索的条件;最终将SearchSourceBuilder类设置到SearchRequest中,代表填充条件完毕; -
QueryBuilders :查询条件构建对象,用于构建不同类型的查询;
QueryBuilders 中的方法 | 对应查询 |
---|
matchQuery/matchAllQuery | queryDSL | boolQuery/must/mustNot | query filter | matchPhraseQuery | phrase search | termQuery | term query | queryStringQuery | query string/string search |
QueryBuilders更多用法:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-query-builders.html
package com.es.demo;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
public class Demo06_Search_TransportClient_Prepare {
private Settings settings;
private TransportClient client;
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "elasticsearch").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
@After
public void after() throws Exception {
client.close();
}
public void print(SearchResponse res) {
System.out.println("查询到: " + res.getHits().getTotalHits().value);
SearchHits hits = res.getHits();
for (SearchHit hit : hits) {
System.out.println("score: " + hit.getScore());
System.out.println(hit.getSourceAsString());
System.out.println("------------");
}
}
@Test
public void queryDSL() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setTypes("_doc")
.setQuery(QueryBuilders.matchQuery("title", "xiaomi"))
.get();
print(res);
}
@Test
public void queryFilter() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setQuery(
QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("title", "huawei"))
.mustNot(QueryBuilders.matchQuery("title", "youxi"))
).get();
print(res);
}
@Test
public void phraseSearch() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setQuery(QueryBuilders.matchPhraseQuery("title", "huawei 5G"))
.get();
print(res);
}
@Test
public void termQuery() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setQuery(QueryBuilders.termQuery("title", "huawei 5G"))
.get();
print(res);
}
@Test
public void stringSearch() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setTypes("_doc")
.setQuery(QueryBuilders.queryStringQuery("title:4G"))
.setQuery(QueryBuilders.queryStringQuery("category:youxi"))
.setQuery(QueryBuilders.queryStringQuery("price:[2000 TO 5000]"))
.addSort("price", SortOrder.DESC)
.setFrom(0)
.setSize(3)
.get();
print(res);
}
@Test
public void queryString() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setQuery(
QueryBuilders.queryStringQuery("[2000 TO 3000]").field("price")
)
.get();
print(res);
}
@Test
public void testIdQuery() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setTypes("article")
.setQuery(QueryBuilders.idsQuery().addIds("1", "2"))
.get();
print(res);
}
}
2)TransportClient搜索
使用TransportClient 类提供的prepareSearch 方法进行搜索,同样使用QueryBuilders 进行搜索条件的构建,只是写法不同而已;
package com.es.demo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
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.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
public class Demo07_Search_TransportClient {
private Settings settings;
private TransportClient client;
public void print(SearchResponse res) {
System.out.println("查询到: " + res.getHits().getTotalHits().value);
SearchHits hits = res.getHits();
for (SearchHit hit : hits) {
System.out.println("score: " + hit.getScore());
System.out.println(hit.getSourceAsString());
System.out.println("------------");
}
}
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "my-cluster").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
System.out.println(client.getClass());
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void stringSearch() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.queryStringQuery("title:shou*"));
builder.query(QueryBuilders.queryStringQuery("category:youxi"));
builder.query(QueryBuilders.queryStringQuery("price:[2000 TO 5000]"));
builder.sort("price", SortOrder.DESC);
builder.from(0);
builder.size(2);
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest).get();
System.out.println("查询到: " + res.getHits().getTotalHits().value);
SearchHits hits = res.getHits();
for (SearchHit hit : hits) {
System.out.println("score: " + hit.getScore());
System.out.println(hit.getSourceAsString());
System.out.println("------------");
}
}
@Test
public void queryDSL() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchQuery("title", "xiaomi"));
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest).get();
print(res);
}
@Test
public void queryFilter() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(
QueryBuilders.boolQuery().
must(QueryBuilders.matchQuery("title", "huawei")).
mustNot(QueryBuilders.matchQuery("title", "youxi"))
);
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest).get();
print(res);
}
@Test
public void phraseSearch() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchPhraseQuery("title", "huawei 5G"));
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest).get();
print(res);
}
@Test
public void termQuery() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termQuery("title", "huawei 5G"));
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest).get();
print(res);
}
@Test
public void queryString() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(
QueryBuilders.queryStringQuery("[2000 TO 3000]").field("price")
);
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest).get();
print(res);
}
}
1.2.4 高亮搜索
Java在实现ES的高亮搜索主要就在于一个类:HighlightBuilder 。该类封装了高亮搜索的条件,如高亮字段/高亮前后缀等;
HighlightBuilder具体用法:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-search.html
package com.es.demo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
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.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.util.Map;
public class Demo08_Highlight_Search_TransportClient {
private Settings settings;
private TransportClient client;
public void print(SearchResponse res) {
System.out.println("查询到: " + res.getHits().getTotalHits().value);
SearchHits hits = res.getHits();
for (SearchHit hit : hits) {
System.out.println("score: " + hit.getScore());
System.out.println(hit.getSourceAsString());
System.out.println("------------");
}
}
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "elasticsearch").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void searchQueryHighQuery() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.queryStringQuery("title:4G"));
HighlightBuilder highBuilder = new HighlightBuilder().field("title").preTags("<font color='red'>").postTags("</font>");
builder.highlighter(highBuilder);
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest).get();
SearchHits results = res.getHits();
for (SearchHit result : results) {
String sourceAsString = result.getSourceAsString();
System.out.println(sourceAsString);
Map<String, HighlightField> high = result.getHighlightFields();
System.out.println(high.get("title").fragments()[0].string());
System.out.println("----------------");
}
}
@Test
public void transportClientHighQuery() throws Exception {
HighlightBuilder highBuilder = new HighlightBuilder().field("title").preTags("</font style='red'>").postTags("</font>");
SearchResponse res = client.prepareSearch("goodsindex")
.setTypes("_doc")
.setQuery(QueryBuilders.queryStringQuery("title:4G"))
.highlighter(highBuilder)
.get();
SearchHits results = res.getHits();
for (SearchHit result : results) {
String sourceAsString = result.getSourceAsString();
System.out.println(sourceAsString);
Map<String, HighlightField> high = result.getHighlightFields();
System.out.println(high.get("title").fragments()[0].string());
System.out.println("----------------");
}
}
}
1.2.5 聚合搜索
package com.es.demo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.util.List;
public class Demo09_Aggs_TransportClient {
private Settings settings;
private TransportClient client;
public void print(SearchResponse res) {
System.out.println("查询到: " + res.getHits().getTotalHits().value);
SearchHits hits = res.getHits();
for (SearchHit hit : hits) {
System.out.println("score: " + hit.getScore());
System.out.println(hit.getSourceAsString());
System.out.println("------------");
}
}
@Before
public void before() throws Exception {
settings = Settings.builder().put("cluster.name", "my-cluster").build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void aggs_searchRequest() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder searchBuilder =
new SearchSourceBuilder().aggregation(AggregationBuilders.terms("group_by_category").field("category"));
searchRequest.source(searchBuilder);
SearchResponse res = client.search(searchRequest).get();
Aggregations aggregations = res.getAggregations();
Terms group_by_category = aggregations.get("group_by_category");
List<? extends Terms.Bucket> buckets = group_by_category.getBuckets();
for (Terms.Bucket bucket : buckets) {
String key = bucket.getKeyAsString();
System.out.println("key:" + key);
long docCount = bucket.getDocCount();
System.out.println("docCount:" + docCount);
System.out.println("--------------------");
}
}
@Test
public void aggs_transportClientSearch() throws Exception {
SearchResponse res = client.prepareSearch("goodsindex")
.setQuery(QueryBuilders.matchAllQuery())
.addAggregation(AggregationBuilders.terms("group_by_category").field("category"))
.setSize(0)
.get();
Aggregations aggregations = res.getAggregations();
Terms group_by_category = aggregations.get("group_by_category");
List<? extends Terms.Bucket> buckets = group_by_category.getBuckets();
for (Terms.Bucket bucket : buckets) {
String key = bucket.getKeyAsString();
System.out.println("key:" + key);
long docCount = bucket.getDocCount();
System.out.println("docCount:" + docCount);
System.out.println("--------------------");
}
}
}
1.3 Low Level REST Client
Low Level REST Client :ElasticSearch官方的低级客户端。之所以称为低级客户端,是因为它几乎没有帮助 Java 用户构建请求或解析响应。它只处理请求的路径和查询字符串构造;请求响应后,只是将响应的数据直接响应给客户端,并没有做其他处理;
官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/index.html
Low Level REST Client 中相关的类:
-
RestClient :用于发送一次HTTP请求到ElasticSearch服务器 -
Request :用于封装一次HTTP请求,如请求方式/请求地址/请求体等 -
Response :RestClient执行完请求后得到的响应;
package com.es.demo;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.StatusLine;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
public class Demo10_RestClient {
private RestClient restClient;
public void print(SearchResponse res) {
System.out.println("查询到: " + res.getHits().getTotalHits().value);
SearchHits hits = res.getHits();
for (SearchHit hit : hits) {
System.out.println("score: " + hit.getScore());
System.out.println(hit.getSourceAsString());
System.out.println("------------");
}
}
@Before
public void before() throws Exception {
restClient = RestClient.builder(
new HttpHost("localhost", 9200, "http")
).build();
}
@After
public void after() throws Exception {
restClient.close();
}
@Test
public void test1() throws Exception {
Request request = new Request(
"GET",
"/");
Response response = restClient.performRequest(request);
HttpEntity entity = response.getEntity();
System.out.println("entity: " + entity);
System.out.println(EntityUtils.toString(entity));
System.out.println("-----------------");
Header[] headers = response.getHeaders();
System.out.println("headers: " + Arrays.toString(headers));
System.out.println("-----------------");
StatusLine statusLine = response.getStatusLine();
System.out.println("statusLine: " + statusLine);
System.out.println("-----------------");
}
@Test
public void test2() throws Exception {
Request request = new Request(
"GET",
"/goodsindex/_doc/_search");
Response response = restClient.performRequest(request);
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.toString(entity));
}
@Test
public void test3() throws Exception {
Request request = new Request(
"GET",
"/goodsindex/_doc/_search");
String requestEntityJson = "{\n" +
" \"query\": {\n" +
" \"match\": {\n" +
" \"title\": \"5g\"\n" +
" }\n" +
" }\n" +
" }";
HttpEntity httpEntity = new NStringEntity(requestEntityJson, ContentType.APPLICATION_JSON);
request.setEntity(httpEntity);
Response response = restClient.performRequest(request);
HttpEntity responseEntity = response.getEntity();
System.out.println(EntityUtils.toString(responseEntity));
}
@Test
public void test4() throws Exception {
Request request = new Request(
"GET",
"/goodsindex/_doc/_search");
String requestEntityJson = "{\n" +
" \"query\": {\n" +
" \"match\": {\n" +
" \"title\": \"shouji\"\n" +
" }\n" +
" },\n" +
" \"sort\": [\n" +
" {\n" +
" \"price\": {\n" +
" \"order\": \"desc\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }";
request.setJsonEntity(requestEntityJson);
Response response = restClient.performRequest(request);
HttpEntity responseEntity = response.getEntity();
System.out.println(EntityUtils.toString(responseEntity));
}
@Test
public void test5() throws Exception {
Request request = new Request(
"POST",
"/goodsindex/_doc/100");
String requestEntityJson = "{\n" +
" \"name\":\"meizu shouji\",\n" +
" \"title\":\"meizu 4G gaoqing youxi shouji\",\n" +
" \"price\":1899,\n" +
" \"category\":[\"youxi\",\"4G\",\"gaoqing\"]\n" +
" }";
request.setJsonEntity(requestEntityJson);
request.addParameter("pretty", "true");
Response response = restClient.performRequest(request);
HttpEntity responseEntity = response.getEntity();
System.out.println(EntityUtils.toString(responseEntity));
}
@Test
public void test6() throws Exception {
Request request = new Request(
"PUT",
"/goodsindex/_doc/100");
String requestEntityJson = "{\n" +
" \"name\":\"meizu shouji\",\n" +
" \"title\":\"meizu 5G paizhao shouji\",\n" +
" \"price\":2899,\n" +
" \"category\":[\"paizhao\",\"5G\",\"gaoqing\"]\n" +
" }";
request.setJsonEntity(requestEntityJson);
request.addParameter("pretty", "true");
Response response = restClient.performRequest(request);
HttpEntity responseEntity = response.getEntity();
System.out.println(EntityUtils.toString(responseEntity));
}
@Test
public void test7() throws Exception {
Request request = new Request(
"DELETE",
"/goodsindex/_doc/100");
request.addParameter("pretty", "true");
Response response = restClient.performRequest(request);
HttpEntity responseEntity = response.getEntity();
System.out.println(EntityUtils.toString(responseEntity));
}
}
1.4 High Level REST Client
Java 高级 REST 客户端在 Java 低级 REST 客户端之上运行。它的主要目标是公开 API 特定的方法,接受请求对象作为参数并返回响应对象,以便请求编组和响应解组由客户端本身处理。要求Elasticsearch版本为2.0 或者更高。
官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/index.html
- High Level REST Client中相关的类:High Level REST Client和TransportClient一样支持
IndexRequest ,DeleteRequest ,UpdateRequest ,GetRequest ,SearchRequest ,因此用法和我们之前使用TransportClient类似;
package com.es.demo;
import com.es.entity.Goods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
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.After;
import org.junit.Before;
import org.junit.Test;
public class Demo11_RestHighLevelClient {
private RestHighLevelClient client;
public void print(SearchResponse res) {
System.out.println("查询到: " + res.getHits().getTotalHits().value);
SearchHits hits = res.getHits();
for (SearchHit hit : hits) {
System.out.println("score: " + hit.getScore());
System.out.println(hit.getSourceAsString());
System.out.println("------------");
}
}
@Before
public void before() throws Exception {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")
)
);
}
@After
public void after() throws Exception {
client.close();
}
@Test
public void insert() throws Exception {
Goods goods = new Goods("11",
"meizu shouji", "meizu 5G zhineng paizhao shouji",
2899.0D, new String[]{"5G", "zhineng", "paizhao"}
);
String goodsJson = new ObjectMapper().writeValueAsString(goods);
IndexRequest indexRequest = new IndexRequest("goodsindex", "_doc", "11");
indexRequest.source(goodsJson, XContentType.JSON);
client.index(indexRequest, RequestOptions.DEFAULT);
}
@Test
public void delete() throws Exception {
DeleteRequest deleteRequest = new DeleteRequest("goodsindex", "_doc", "1");
client.delete(deleteRequest, RequestOptions.DEFAULT);
}
@Test
public void update() throws Exception {
UpdateRequest updateRequest = new UpdateRequest("goodsindex", "_doc", "2");
Goods goods = new Goods("2",
"zhongxing shouji", "zhongxing 4G youxi shouji",
2899.0D, new String[]{"4G", "youxi"});
String goodsJson = new ObjectMapper().writeValueAsString(goods);
updateRequest.doc(goodsJson, XContentType.JSON);
client.update(updateRequest, RequestOptions.DEFAULT);
}
@Test
public void query() throws Exception {
GetRequest getRequest = new GetRequest("goodsindex", "_doc", "2");
GetResponse res = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(res.getSourceAsString());
}
@Test
public void searchRequest() throws Exception {
SearchRequest searchRequest = new SearchRequest("goodsindex");
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.queryStringQuery("title:meizu"));
searchRequest.source(builder);
SearchResponse res = client.search(searchRequest, RequestOptions.DEFAULT);
print(res);
}
}
1.5 SQL搜索ElasticSearch
1)开启ES白金版功能
2)示例代码
<repositories>
<repository>
<id>elastic.co</id>
<url>https://artifacts.elastic.co/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>x-pack-sql-jdbc</artifactId>
<version>7.6.2</version>
</dependency>
</dependencies>
package com.es.demo;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Demo12_ES_JDBC {
@Test
public void test1() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:es://http://localhost:9200");
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("select * from goodsindex");
while (rs.next()) {
System.out.print("name: " + rs.getString("name")+"\t");
System.out.print("title: " + rs.getString("title")+"\t");
System.out.print("price: " + rs.getString("price")+"\t");
System.out.print("category: " + rs.getString("category")+"\t");
System.out.println();
}
connection.close();
}
}
二、Spring Data ElasticSearch
Spring Data ElasticSearch 是SpringData 大家族的一员,Spring Data 的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如MySQL),还是非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提高开发效率。
<?xml version="1.0" encoding="UTF-8"?>
<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>com.es</groupId>
<artifactId>02_ElasticSearch_Template</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/>
</parent>
<properties>
<elasticsearch.version>7.6.2</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
</project>
2.1 Template 查询
SpringData家族为大部分产品都提供了查询模板类,例如JdbcTemplate、RedisTemplate、RabbitTempalte等简化我们的操作;同样,SpringDataElasticSearch提供了ElasticsearchRestTemplate类来简化Java操作ES的代码;
- 在SpringDataElasticSearch官网中提供有四种操作ES的相关类:
IndexOperations :有关于索引相关操作,如创建或删除索引。DocumentOperations :有关于文档的操作,根据文档的id进行存储、更新和检索文档的操作。SearchOperations :搜索文档相关操作ElasticsearchOperations :结合了DocumentOperations和SearchOperations接口。
Spring官网中提供有ElasticsearchTemplate 与ElasticsearchRestTemplate 两个ES相关模板类,其中ElasticsearchTemplate是使用TransportClient对ElasticsearchOperations 的实现;ElasticsearchRestTemplate 则是使用High Level REST Client 对ElasticsearchOperations 的实现;
Tips:ElasticsearchTemplate从4.0版本起不再使用,使用ElasticsearchRestTemplate代替。
关于实体类定义的详细文档:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.3.RELEASE/reference/html/#elasticsearch.mapping
package com.es.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
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
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "goodsindex", type = "_doc", shards = 1, replicas = 2)
public class Goods {
@Id
private String id;
@Field(index = true, store = false, fielddata = false, type = FieldType.Text, analyzer = "standard", searchAnalyzer = "standard")
private String name;
@Field(analyzer = "standard", searchAnalyzer = "standard")
private String title;
@Field
private Double price;
@Field
private String[] category;
}
import com.es.Application;
import com.es.entity.Goods;
import org.elasticsearch.index.query.QueryBuilders;
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.*;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class Demo01_Options {
@Autowired
private DocumentOperations documentOperations;
@Autowired
private SearchOperations searchOperations;
@Autowired
private ElasticsearchOperations elasticsearchOperations;
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
public void test1() {
IndexOperations indexOperations = elasticsearchOperations.indexOps(Goods.class);
indexOperations.create();
}
@Test
public void test2() {
Goods goods = new Goods(
"1",
"xiaomi shouji",
"xiaomi 5g youxi shouji",
2000.0D,
new String[]{"5g", "youxi"}
);
documentOperations.save(goods);
}
@Test
public void test3() {
NativeSearchQuery query = new NativeSearchQuery(QueryBuilders.matchAllQuery());
SearchHits<Goods> searchHits = searchOperations.search(query, Goods.class);
for (SearchHit<Goods> searchHit : searchHits) {
Goods goods = searchHit.getContent();
System.out.println(goods);
}
}
@Test
public void test4() {
Goods goods = elasticsearchOperations.get("1", Goods.class);
System.out.println(goods);
}
}
- ElasticsearchRestTemplate 示例代码:
import com.es.Application;
import com.es.entity.Goods;
import org.elasticsearch.index.query.QueryBuilders;
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.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class Demo02_Template {
@Autowired
private ElasticsearchRestTemplate restTemplate;
@Test
public void insert() {
Goods goods = new Goods(
"1",
"huawei shouji",
"huawei 5G youxi shouji",
1889.0D,
new String[]{"youxi", "5G"}
);
restTemplate.save(goods, IndexCoordinates.of("goodsindex"));
}
@Test
public void delete() {
restTemplate.delete("2", IndexCoordinates.of("goodsindex"));
}
@Test
public void update() {
Document goodsDoc = Document.create();
goodsDoc.append("id", "1");
goodsDoc.append("name", "meizu shouji");
goodsDoc.append("title", "meizu 4G paizhao shouji");
goodsDoc.append("double", 1889.0D);
goodsDoc.append("category", new String[]{"paizhao", "4G"});
UpdateQuery updateQuery = UpdateQuery.builder("1")
.withDocument(goodsDoc)
.build();
restTemplate.update(updateQuery, IndexCoordinates.of("goodsindex"));
}
@Test
public void query() {
Goods goods = restTemplate.get("1", Goods.class, IndexCoordinates.of("goodsindex"));
System.out.println(goods);
}
@Test
public void queryForNative() {
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery())
.build();
SearchHits<Goods> goodsSearchHits = restTemplate.search(query, Goods.class, IndexCoordinates.of("goodsindex"));
for (SearchHit<Goods> goodsHit : goodsSearchHits) {
Goods goods = goodsHit.getContent();
System.out.println(goods);
}
}
}
2.2 Repositories 查询
package com.dfbz.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
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
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "goodsindex", type = "_doc")
public class Goods {
@Id
private String id;
@Field(index = true, store = false, fielddata = false, type = FieldType.Text, analyzer = "standard", searchAnalyzer = "standard")
private String name;
@Field
private String title;
@Field
private Double price;
@Field
private String[] category;
}
package com.dfbz.dao;
import com.dfbz.entity.Goods;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface GoodsDao extends ElasticsearchRepository<Goods,String> {
}
2.2.1 普通增删改查
package com.dfbz.demo;
import com.dfbz.Application;
import com.dfbz.dao.GoodsDao;
import com.dfbz.entity.Goods;
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.PageRequest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class Demo01_CRUD {
@Autowired
private GoodsDao goodsDao;
@Test
public void findAll() {
Iterable<Goods> goodsList = goodsDao.findAll(PageRequest.of(2,1));
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
@Test
public void findById() {
Goods goods = goodsDao.findById("1").get();
System.out.println(goods);
}
@Test
public void insert() {
Goods goods = new Goods(
"1",
"vivo shouji",
"vivo 5G paizhao shouji",
3889.0D,
new String[]{"paizhao", "5G"}
);
Goods goods2 = new Goods(
"2",
"meizu shouji",
"meizu 4G youxi shouji",
3889.0D,
new String[]{"youxi", "5G"}
);
goodsDao.saveAll(Arrays.asList(goods,goods2));
}
@Test
public void update() {
Goods goods = new Goods(
"8",
"oppo shouji",
"oppo 5G paizhao shouji",
2889.0D,
new String[]{"paizhao", "5G"}
);
goodsDao.save(goods);
}
@Test
public void delete() {
goodsDao.deleteById("8");
}
}
2.2.2 自定义方法命名查询
package com.es.dao;
import com.es.entity.Goods;
import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.annotations.HighlightParameters;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface GoodsDao extends ElasticsearchRepository<Goods, String> {
List<Goods> findByTitle(String title);
List<Goods> findByPriceBetween(Double start, Double end);
List<Goods> findByTitleLike(String title);
@Query("{\"match\": {\"title\": {\"query\": \"?0\"}}}")
List<Goods> searchByQueryString(String title);
@Highlight(
fields = {
@HighlightField(
name = "name",
parameters = @HighlightParameters(preTags = "<font color='red'>",postTags = "</font>")
),
@HighlightField(
name = "title",
parameters = @HighlightParameters(preTags = "<font color='red'>",postTags = "</font>")
)
}
)
List<SearchHit<Goods>> findByTitleOrName(String title, String name);
}
package com.es.demo;
import com.es.Application;
import com.es.dao.GoodsDao;
import com.es.entity.Goods;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
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.SearchHit;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Map;
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class Demo02_NamedQuery {
@Autowired
private GoodsDao goodsDao;
@Test
public void findByTitle() {
List<Goods> goodsList = goodsDao.findByTitleLike("x");
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
@Test
public void findByPriceBetween() {
List<Goods> goodsList = goodsDao.findByPriceBetween(2000.0D, 4000.0D);
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
@Test
public void findByTitleLike() {
List<Goods> goodsList = goodsDao.findByTitleLike("xiao");
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
@Test
public void searchQuery() {
MatchQueryBuilder searchQuery = QueryBuilders.matchQuery("title", "meizu 5G");
Iterable<Goods> goodsList = goodsDao.search(searchQuery);
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
@Test
public void anno() {
List<Goods> goodsList = goodsDao.searchByQueryString("xiaomi");
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
@Test
public void highQuery() {
List<SearchHit<Goods>> goodsList = goodsDao.findByTitleOrName("shouji", "shouji");
for (SearchHit<Goods> goodsHit : goodsList) {
Map<String, List<String>> highlightFields = goodsHit.getHighlightFields();
System.out.println(highlightFields);
}
}
}
需要注意的是,SpringDatatElasticSearch支持的query注解查询语法有些变化:
GET goodsindex/_doc/_search
{
"query": {
"match": {
"title": "shouji"
}
}
}
改为:
GET goodsindex/_doc/_search
{
"query": {
"match": {
"title": {
"query":"xiaomi"
}
}
}
}
------------------------------------------
GET goodsindex/_doc/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "huawei"
}
}
],
"must_not": [
{
"match": {
"title": "youxi"
}
}
]
}
}
}
改为:
GET goodsindex/_doc/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title":{
"query":"xiaomi"
}
}
}
],
"must_not": [
{
"match": {
"title": {
"query":"youxi"
}
}
}
]
}
}
}
---------------------------------------------------------------
GET goodsindex/_doc/_search
{
"query": {
"match": {
"title": "xiaomi"
}
}
}
改为:
GET goodsindex/_doc/_search
{
"query": {
"match": {
"title": {
"query": "xiaomi"
}
}
}
}
记得点赞~~
|