我们的应用经常需要添加检索功能,开源的ElasticSearch是目前全文搜索引擎的首选,他可以快速的存储、搜索和分析海量数据,springboot通过整合spring data elasticsearch为我们提供非常便捷的检索功能支持
elasticsearch:elasticsearch是一个分布式搜素服务,提供restful api,底层基于lucene,采用多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github等大型的站点也是采用了elasticsearch作为其搜索服务。
在docker下安装ES:
docker pull elasticsearch
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -e "discovery.type=single-node" -d -p 9200:9200 -p 9300:9300 --name myes01 镜像id
# -e后面设置占用内存为256M,9200是与外部web通信端口,9300是ES各节点通信端口&单节点启动
访问虚拟机地址:9200端口,正确将会出现以下页面:(我之后改成了7.6.2版本,自行修改即可)
ES集群大致结构:
测试操作:这里使用postman来完成
添加员工信息:
查询:
查询是否存在该员工:(200表示存在,404notfound表示不存在)
删除:
修改的话只需要用put方式放入修改后的数据即可。
查询所有员工:
查询lastname为smith的所有员工:
使用查询表达式:
全文搜索:(会列出相关性)
短语搜索:(将about中的内容作为一个整体来进行搜索)
高亮搜索:
这里准备一个elasticsearch的可视化管理工具:elasticsearch-head
首先从gitthub上克隆下项目:
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start # 然后就可以打开localhost:9100/访问了
如果npm install一直卡住不动的话可以设置代理:
npm config set registry https://registry.npm.taobao.org
但是此时却连接不上elasticsearch,因为端口不一样,相当于是跨域了,解决跨域问题:
再次连接可以发现成功了:
tips1:ELK三剑客,ElasticSearch、LogStash、Kibana(ELK一般用于日志收集与分析、也可以用于其他数据分析和收集)
首先确保ES的版本和springboot中ElasticSearch的版本一致:
配置ElasticSearch所在的linux主机地址:
spring.elasticsearch.rest.uris=http://192.168.192.129:9200
@Autowired
private RestHighLevelClient client;
@Test
void contextLoads() {
User user = new User(1,"张三",21);
IndexRequest indexRequest = new IndexRequest("myhome").id("1"); //构建索引并设置id
indexRequest.source(JSON.toJSONString(user), XContentType.JSON); //添加内容
try {
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(indexResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取、查询是否存在操作
*/
@Test
public void fun1() throws IOException {
//获取索引操作
// GetIndexRequest getIndexRequest = new GetIndexRequest().indices("myhome");
// GetIndexResponse getIndexResponse = client.indices().get(getIndexRequest, RequestOptions.DEFAULT);
// System.out.println(getIndexResponse);
GetRequest getRequest = new GetRequest("myhome","1");//判断索引myhome中是否存在id=1(不是数据内部的id)的数据
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println("是否存在:"+exists);
GetResponse getResponse = client.get(getRequest,RequestOptions.DEFAULT);
System.out.println(getResponse);
User user = JSON.parseObject(getResponse.getSourceAsString(), User.class);
System.out.println("从json转为对象:"+user);
}
/**
* 删除操作
*/
@Test
public void fun2(){
//删除索引
// DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("myhome");
// client.indices().delete(deleteIndexRequest,RequestOptions.DEFAULT);
DeleteRequest deleteRequest = new DeleteRequest("myhome").id("1");
try {
DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(deleteResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 更新操作
*/
@Test
public void fun3(){
UpdateRequest updateRequest = new UpdateRequest("myhome","2");
updateRequest.doc(JSON.toJSONString(new User(999, "神秘人", 999)),XContentType.JSON);
try {
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(updateResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取多个
*/
@Test
public void fun4(){
MultiGetRequest multiGetRequest = new MultiGetRequest();
multiGetRequest.add("myhome","1");
multiGetRequest.add("myhome","2");
try {
MultiGetResponse multiGetItemResponses = client.mget(multiGetRequest, RequestOptions.DEFAULT);
for(MultiGetItemResponse temp : multiGetItemResponses.getResponses()){
System.out.println(temp.getResponse());
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 批量插入
*/
@Test
public void fun5(){
BulkRequest bulkRequest = new BulkRequest();
List<User> list = new ArrayList<>();
list.add(new User(5,"aaa",55));
list.add(new User(6,"bbb",56));
list.add(new User(7,"ccc",57));
list.add(new User(8,"ddd",58));
list.add(new User(9,"eee",59));
for(int i = 0;i < list.size();i++){
// bulkRequest.add(new UpdateRequest()); //批量更新
// bulkRequest.add(new DeleteRequest()); //批量删除
bulkRequest.add(new IndexRequest("myhome").id(""+(i+1))
.source(JSON.toJSONString(list.get(i)),XContentType.JSON));
}
try {
BulkResponse bulkItemResponses = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println("插入失败?:"+bulkItemResponses.hasFailures());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据条件查询
*/
@Test
public void fun6(){
SearchRequest searchRequest = new SearchRequest().indices("myhome");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// QueryBuilder queryBuilder = new MatchAllQueryBuilder(); //查询所有数据
QueryBuilder queryBuilder = QueryBuilders.termQuery("age","56"); //按照条件查询
searchSourceBuilder.query(queryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = null;
try {
searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
for (SearchHit searchHit : searchResponse.getHits().getHits()) {
System.out.println(searchHit.getSourceAsString());//这里就不转为对象了
}
}
上述操作也可以通过springdata来完成,ElasticsearchRestTemplate,操作大同小异,这里不一一赘述了。