# 基於 Elasticsearch 搜尋商品 搜索篇
踩坑中ing , 修改為 Java high-level REST client 連接 Elasticsearch
https://blog.csdn.net/u014646662/article/details/94718834
ElasticSearch 7.x 後續版本不支持指定索引
# 基於 docker install local ik zip
由於我的 windwos 10 不支援 docker 懶得重灌 所以我用 docker tool
![](https://i.imgur.com/piQ7dIK.png)
可以看到這邊共享資料夾
重新新增 container
>
docker run --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -v /c/Users/test/:/data -d docker.elastic.co/elasticsearch/elasticsearch:7.6.2
>
下在ik zip 至我們的
>C:\Users\test
>
![](https://i.imgur.com/NXHCX3o.png)
>/usr/share/elasticsearch/bin/elasticsearch-plugin install file:///data/elasticsearch-analysis-ik-7.6.2.zip
>
本地安裝 docker 之後exit docker restart es 重啟完成就可以使用我們的 ik 對 中文進行分詞了
![](https://i.imgur.com/ojznjvB.png)
後面對昨天的功能進行改版一下 後續改版 已經不支持索引 預設為 _doc 所以 發現這部分資料還是比較少的我們來補足一下
# esController
```java
@Controller
@RequestMapping("/esProduct")
public class esitemConntroller {
@Autowired
private esitemService esProductService;
@RequestMapping(value = "/createIndexMapping", method = RequestMethod.GET)
@ResponseBody
public String createIndexMapping() {
return esProductService.createIndexwithMapping();
}
@RequestMapping(value = "/checkIndexMapping/{index}", method = RequestMethod.GET)
@ResponseBody
public String checkIndexMapping(@PathVariable String index) {
return esProductService.checkIndexMapping(index);
}
@RequestMapping(value = "/deleteIndex/{index}", method = RequestMethod.GET)
@ResponseBody
public String deleteIndex(@PathVariable String index) {
return esProductService.deleteIndex(index);
}
// 新增 document
@RequestMapping(value = "/createDocument/{index}/{type}/{id}/{key}/{value}/{key2}/{value2}", method = RequestMethod.GET)
@ResponseBody
public String createDocument(@PathVariable String index,@PathVariable String type,
@PathVariable String id,@PathVariable String key,@PathVariable String value
,@PathVariable String key2,@PathVariable String value2) {
return esProductService.createDocument(index, type, id, key, value, key2, value2);
}
// 更新 document
@RequestMapping(value = "/updateDocument/{index}/{type}/{id}/{key2}/{value2}", method = RequestMethod.GET)
@ResponseBody
public String updateDocument(@PathVariable String index,@PathVariable String type,
@PathVariable String id,@PathVariable String key,@PathVariable String value
,@PathVariable String key2,@PathVariable String value2) {
return esProductService.updateDocument(index, type, id, key, value, key2, value2);
}
// 批量新增 document
@RequestMapping(value = "/bulkDocument", method = RequestMethod.GET)
@ResponseBody
public String bulkDocument() {
return esProductService.bulkDocument();
}
// 刪除 document
@RequestMapping(value = "/deleteDocument/{documentCount}", method = RequestMethod.GET)
@ResponseBody
public String deleteDocument(@PathVariable Integer documentCount) {
return esProductService.deleteDocument(documentCount);
}
// 搜尋 Document
@RequestMapping(value = "/searchDocument/{index}/{key}/{value}", method = RequestMethod.GET)
@ResponseBody
public String searchDocument(@PathVariable String index,@PathVariable String key,@PathVariable String value) {
return esProductService.searchDocument(index, key, value);
}
```
# Serverimpl
```java
@Service
public final class esitemServiceimpl implements esitemService {
private static final String HOST = "192.168.99.100";
// Elasticsearch查询服务器使用9200端口,我们可以通过RESTful API直接查询数据库。
private static final int PORT_ONE = 9200;
// REST服务器使用9201端口,外部客户端可以使用它来连接和执行操作。
private static final int PORT_TWO = 9201;
// 通信方式
private static final String SCHEME = "http";
// 高级客户端实例
private static RestHighLevelClient restHighLevelClient;
// Jackson 的转换类
private static ObjectMapper objectMapper = new ObjectMapper();
// 索引名称
private static final String INDEX = "persondata";
// 索引类型
private static final String TYPE = "person";
public esitemServiceimpl() {
super();
makeConnection();
}
private static synchronized RestHighLevelClient makeConnection() {
if(restHighLevelClient == null) {
restHighLevelClient = new RestHighLevelClient(
RestClient.builder(
new HttpHost(HOST, PORT_ONE, SCHEME),
new HttpHost(HOST, PORT_TWO, SCHEME)));
}
System.out.println("RestHighLevelClient initialization successful!");
return restHighLevelClient;
}
private static synchronized void closeConnection() throws IOException {
restHighLevelClient.close();
restHighLevelClient = null;
}
@Override
public Person insertPerson(Person person){
person.setPersonId(UUID.randomUUID().toString());
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("personId", person.getPersonId());
dataMap.put("name", person.getName());
IndexRequest indexRequest = new IndexRequest(INDEX, TYPE, person.getPersonId())
.source(dataMap);
try {
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
e.getDetailedMessage();
} catch (java.io.IOException ex){
ex.getLocalizedMessage();
}
return person;
}
@Override
public Person getPersonById(String id){
GetRequest getPersonRequest = new GetRequest(INDEX, TYPE, id);
GetResponse getResponse = null;
try {
getResponse = restHighLevelClient.get(getPersonRequest, RequestOptions.DEFAULT);
} catch (java.io.IOException e){
e.getLocalizedMessage();
}
return getResponse != null ?
objectMapper.convertValue(getResponse.getSourceAsMap(), Person.class) : null;
}
@Override
public Person updatePersonById(String id, Person person){
UpdateRequest updateRequest = new UpdateRequest(INDEX, TYPE, id)
.fetchSource(true); // 更新后获取对象
try {
String personJson = objectMapper.writeValueAsString(person);
updateRequest.doc(personJson, XContentType.JSON);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
return objectMapper.convertValue(updateResponse.getGetResult().sourceAsMap(), Person.class);
}catch (JsonProcessingException e){
e.getMessage();
} catch (java.io.IOException e){
e.getLocalizedMessage();
}
System.out.println("Unable to update person");
return null;
}
@Override
public void deletePersonById(String id) {
DeleteRequest deleteRequest = new DeleteRequest(INDEX, TYPE, id);
try {
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
} catch (java.io.IOException e){
e.getLocalizedMessage();
}
}
@Override
public String createIndexwithMapping() {
// TODO Auto-generated method stub
String result="";
try {
CreateIndexRequest request = new CreateIndexRequest("pybbs");
request.settings(Settings.builder()
.put("index.number_of_shards", 1)
.put("index.number_of_shards", 5));
XContentBuilder mappingBuilder = JsonXContent.contentBuilder()
.startObject()
.startObject("properties")
.startObject("title")
.field("type", "text")
.field("analyzer", "ik_smart") //ik_smart
.field("index", "true")
.endObject()
.startObject("content")
.field("type", "text")
.field("analyzer", "ik_max_word") // ik_max_word 这个分词器是ik的,可以去github上搜索安装es的ik分词器插件
.field("index", "true")
.endObject()
.endObject()
.endObject();
request.mapping(mappingBuilder);
CreateIndexResponse response;
response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
System.out.println(response.toString());
result =response.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
@Override
public String checkIndexMapping(String Index) {
String result="";
GetIndexRequest request = new GetIndexRequest();
request.indices(Index);
request.local(false);
request.humanReadable(true);
boolean exists;
try {
exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
result = ("result: {"+ exists + "}");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return result;
}
@Override
public String deleteIndex(String index) {
String result="";
DeleteIndexRequest request = new DeleteIndexRequest(index);
request.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
AcknowledgedResponse response;
try {
response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
result = "result: {"+response.isAcknowledged()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return result;
}
@Override
public String createDocument(String index, String type , String id , String key ,String value, String key2 ,String value2) {
String result="";
Map<String, Object> map = new HashMap<>();
map.put(key, value);
map.put(key2, value2);
IndexRequest request = new IndexRequest(index, type, id); // 这里最后一个参数是es里储存的id,如果不填,es会自动生成一个,个人建议跟自己的数据库表里id保持一致,后面更新删除都会很方便
request.source(map);
try {
IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
result = "result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// not exist: result: code: 201, status: CREATED
// exist: result: code: 200, status: OK
// TODO Auto-generated method stub
return result;
}
@Override
public String updateDocument(String index, String type , String id , String key ,String value, String key2 ,String value2) {
String result="";
UpdateRequest request = new UpdateRequest(index, type, id);
Map<String, Object> map = new HashMap<>();
map.put(key, value);
map.put(key2, value2);
request.doc(map);
try {
UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
result ="result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return result;
}
@Override
public String bulkDocument() {
String result="";
BulkRequest requests = new BulkRequest();
Map<String, Object> map1 = new HashMap<>();
map1.put("title", "我是台灣人 ,im taiwan");
IndexRequest request1 = new IndexRequest("pybbs", "_doc", "1");
request1.source(map1);
requests.add(request1);
Map<String, Object> map2 = new HashMap<>();
map2.put("title", "高雄市安安");
IndexRequest request2 = new IndexRequest("pybbs", "_doc", "2");
request2.source(map2);
requests.add(request2);
Map<String, Object> map3 = new HashMap<>();
map3.put("title", "台北安安");
IndexRequest request3 = new IndexRequest("pybbs", "_doc", "3");
request3.source(map3);
requests.add(request3);
try {
BulkResponse responses = restHighLevelClient.bulk(requests, RequestOptions.DEFAULT);
result ="result: code: {"+responses.status().getStatus()+"}, status: {"+ responses.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// not exist: result: code: 200, status: OK
// exist: result: code: 200, status: OK
// TODO Auto-generated method stub
return result;
}
@Override
public String deleteDocument(Integer documentCount) {
String result="";
for (int i = 1; i <= documentCount; i++) {
DeleteRequest request = new DeleteRequest("pybbs", "_doc", String.valueOf(i));
try {
DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
System.out.println("result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}");
result = "result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
// exist: result: code: 200, status: OK
// not exist: result: code: 404, status: NOT_FOUND
// log.info("result: code: {}, status: {}", response.status().getStatus(), response.status().name());
}
// TODO Auto-generated method stub
return result;
}
@Override
public String searchDocument(String index ,String key , String value) {
String result="";
SearchRequest request = new SearchRequest(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchQuery(key, value));
// builder.from(0).size(2); // 分頁
request.source(builder);
SearchResponse response;
try {
response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.toString() + "\n"+response.getTotalShards());
for (SearchHit documentFields : response.getHits()) {
String tmp ="result: {"+ documentFields.toString()+"}, code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}\n";
System.out.println(tmp);
result = result += tmp;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
// log.info(response.toString(), response.getTotalShards());
// TODO Auto-generated method stub
return result;
}
}
```
# service
```java
public interface esitemService {
String createIndexwithMapping() ;
String checkIndexMapping(String Index);
String deleteIndex(String Index);
String createDocument(String index, String type , String id , String key ,String value , String key2 ,String value2);
String updateDocument(String index, String type , String id , String key ,String value, String key2 ,String value2);
String bulkDocument();
String deleteDocument(Integer documentCount);
String searchDocument(String index ,String key , String value);
}
```
來演示一下
# 創建mapping
![](https://i.imgur.com/BURZmmm.png)
http://localhost:8080/esProduct/createIndexMapping
```java
@Override
public String createIndexwithMapping() {
// TODO Auto-generated method stub
String result="";
try {
CreateIndexRequest request = new CreateIndexRequest("pybbs");
request.settings(Settings.builder()
.put("index.number_of_shards", 1)
.put("index.number_of_shards", 5));
XContentBuilder mappingBuilder = JsonXContent.contentBuilder()
.startObject()
.startObject("properties")
.startObject("title")
.field("type", "text")
.field("analyzer", "ik_smart") //ik_smart
.field("index", "true")
.endObject()
.startObject("content")
.field("type", "text")
.field("analyzer", "ik_max_word") // ik_max_word 这个分词器是ik的,可以去github上搜索安装es的ik分词器插件
.field("index", "true")
.endObject()
.endObject()
.endObject();
request.mapping(mappingBuilder);
CreateIndexResponse response;
response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
System.out.println(response.toString());
result =response.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
```
# 檢查 mapping
http://localhost:8080/esProduct/checkIndexMapping/pybbs
![](https://i.imgur.com/c4GeeFb.png)
```java
@Override
public String checkIndexMapping(String Index) {
String result="";
GetIndexRequest request = new GetIndexRequest();
request.indices(Index);
request.local(false);
request.humanReadable(true);
boolean exists;
try {
exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
result = ("result: {"+ exists + "}");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return result;
}
```
# 刪除 index
http://localhost:8080/esProduct/deleteIndex/pybbs
![](https://i.imgur.com/8G48hRJ.png)
```java
@Override
public String deleteIndex(String index) {
String result="";
DeleteIndexRequest request = new DeleteIndexRequest(index);
request.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
AcknowledgedResponse response;
try {
response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
result = "result: {"+response.isAcknowledged()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return result;
}
```
# 新增 documet
http://localhost:8080/esProduct/createDocument/pybbs/_doc/2/title/%E5%8F%B0%E7%81%A3%E4%BD%A0%E5%A5%BD/content/%E5%8F%B0%E5%8C%97
![](https://i.imgur.com/OhoL1qx.png)
http://localhost:8080/esProduct/createDocument/pybbs/_doc/2/title/%E9%A6%99%E6%B8%AF%E4%BD%A0%E5%A5%BD/content/%E5%9C%8B%E5%AE%B6
![](https://i.imgur.com/UNioTQN.png)
![](https://i.imgur.com/YlMy9Ll.png)
```java
@Override
public String createDocument(String index, String type , String id , String key ,String value, String key2 ,String value2) {
String result="";
Map<String, Object> map = new HashMap<>();
map.put(key, value);
map.put(key2, value2);
IndexRequest request = new IndexRequest(index, type, id); // 这里最后一个参数是es里储存的id,如果不填,es会自动生成一个,个人建议跟自己的数据库表里id保持一致,后面更新删除都会很方便
request.source(map);
try {
IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
result = "result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// not exist: result: code: 201, status: CREATED
// exist: result: code: 200, status: OK
// TODO Auto-generated method stub
return result;
}
```
# 更新 document
http://localhost:8080/esProduct/updateDocument/pybbs/_doc/2/title/%E9%A6%99%E6%B8%AF%E4%BD%A0%E5%A5%BD/content/%E6%97%BA%E8%A7%92
![](https://i.imgur.com/8ltrZWW.png)
![](https://i.imgur.com/wlsoa6o.png)
```
@Override
public String updateDocument(String index, String type , String id , String key ,String value, String key2 ,String value2) {
String result="";
UpdateRequest request = new UpdateRequest(index, type, id);
Map<String, Object> map = new HashMap<>();
map.put(key, value);
map.put(key2, value2);
request.doc(map);
try {
UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
result ="result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return result;
}
```
# 批量新增 document
http://localhost:8080/esProduct/bulkDocument
![](https://i.imgur.com/mi7VNNy.png)
![](https://i.imgur.com/XaLTrWm.png)
```java
@Override
public String bulkDocument() {
String result="";
BulkRequest requests = new BulkRequest();
Map<String, Object> map1 = new HashMap<>();
map1.put("title", "我是台灣人 ,im taiwan");
IndexRequest request1 = new IndexRequest("pybbs", "_doc", "1");
request1.source(map1);
requests.add(request1);
Map<String, Object> map2 = new HashMap<>();
map2.put("title", "高雄市安安");
IndexRequest request2 = new IndexRequest("pybbs", "_doc", "2");
request2.source(map2);
requests.add(request2);
Map<String, Object> map3 = new HashMap<>();
map3.put("title", "台北安安");
IndexRequest request3 = new IndexRequest("pybbs", "_doc", "3");
request3.source(map3);
requests.add(request3);
try {
BulkResponse responses = restHighLevelClient.bulk(requests, RequestOptions.DEFAULT);
result ="result: code: {"+responses.status().getStatus()+"}, status: {"+ responses.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// not exist: result: code: 200, status: OK
// exist: result: code: 200, status: OK
// TODO Auto-generated method stub
return result;
}
```
# 刪除 document
http://localhost:8080/esProduct/deleteDocument/3
![](https://i.imgur.com/MzSgtDX.png)
![](https://i.imgur.com/QGakZoR.png)
```java
@Override
public String deleteDocument(Integer documentCount) {
String result="";
for (int i = 1; i <= documentCount; i++) {
DeleteRequest request = new DeleteRequest("pybbs", "_doc", String.valueOf(i));
try {
DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
System.out.println("result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}");
result = "result: code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
// exist: result: code: 200, status: OK
// not exist: result: code: 404, status: NOT_FOUND
// log.info("result: code: {}, status: {}", response.status().getStatus(), response.status().name());
}
// TODO Auto-generated method stub
return result;
}
```
# 搜尋 document
http://localhost:8080/esProduct/searchDocument/pybbs/title/%E5%8F%B0%E7%81%A3
![](https://i.imgur.com/bf5VJOY.png)
http://localhost:8080/esProduct/searchDocument/pybbs/title/%E9%A6%99%E6%B8%AF
![](https://i.imgur.com/Orz7DRD.png)
http://localhost:8080/esProduct/searchDocument/pybbs/title/%E4%BD%A0%E5%A5%BD
![](https://i.imgur.com/Kth0kew.png)
```java
@Override
public String searchDocument(String index ,String key , String value) {
String result="";
SearchRequest request = new SearchRequest(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchQuery(key, value));
// builder.from(0).size(2); // 分頁
request.source(builder);
SearchResponse response;
try {
response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.toString() + "\n"+response.getTotalShards());
for (SearchHit documentFields : response.getHits()) {
String tmp ="result: {"+ documentFields.toString()+"}, code: {"+response.status().getStatus()+"}, status: {"+response.status().name()+"}\n";
System.out.println(tmp);
result = result += tmp;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
// log.info(response.toString(), response.getTotalShards());
// TODO Auto-generated method stub
return result;
}
```