文章目录
- 一、概述
- 二、安装Elastic Search
- 三、了解restful
- 四、集成IK分词器
- 五、命令操作
- 六、Java操作Elastic Search
一、概述
和Lucene一样,都是用来做全文检索(创建索引和搜索索引).只是lucene是全文检索工具包,而ES是全文搜索服务器。
优点:
- 不仅支持java环境
es是服务器,它把原来lucene很复杂的操作封装成了Restful(http)接口.原来要写一大堆代码创建索引. 现在只需发一个http请求就OK(put http://127.0.0.1/user {…}),其他语言也可以发送http请求,所以支持多种开发语言. - 使用方式变得很简单
进行了封装,只需发http请求到服务器就OK - 也能集群环境使用
多个应用服务器(代码)使用的是同一个搜索服务器. - ES本身也可以集群
es支持集群,支持海量数据存储。
ElasticSearch简化了全文检索lucene的使用,同时增加了分布式的特性,使得构建大规模分布式全文检索变得非常容易。
二、安装Elastic Search
相关概念:
(1)Near Realtime(NRT):近实时,两个意思,从写入数据到数据可以被搜索到有一个小延迟(大概1秒);基于es执行搜索和分析可以达到秒级
(2)Index:索引库,包含一堆有相似结构的文档数据,比如可以有一个客户索引,商品分类索引,订单索引,索引有一个名称。一个index包含很多document,一个index就代表了一类类似的或者相同的document。比如说建立一个product index,商品索引,里面可能就存放了所有的商品数据,所有的商品document。
(3)Type:类型,每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field,比如博客系统,有一个索引,可以定义用户数据type,博客数据type,评论数据type。
(4)Document&field:文档,es中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,一条订单数据,通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段。
(5)Cluster:集群,包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常
(6)Node:节点,集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群
(7)shard(ʃɑːrd,分片):单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个lucene index。
(8)replica(ˈreplɪkə,复制品):任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个),默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。
安装:
1)下载
https://www.elastic.co/downloads/elasticsearch
正常请求我们应该在linux或者Docker安装,但是现在我们是学习阶段,就在window上面进行安装
- 安装
解压即可
可以修改内存配置 - 启动
bin/elasticsearch.bat - 测试 -web端口
http://localhost:9200 查询状态
图形界面客户端:
kibana 官方推荐
head,可以直接看到shard和replica
postman
三、了解restful
Restful是一种面向资源的架构风格,可以简单理解为:使用URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作。
get http://127.0.0.1:8080/user/1 获取用户
delete http://127.0.0.1:8080/user/1 删除用户
put http://127.0.0.1:8080/user/ 添加用户
{
“id”:1,
“name”:”zs”
}
Post http://127.0.0.1:8080/user/ 修改用户
{
“id”:1,
“name”:”zs”
}
四、集成IK分词器
以插件的方式集成到Elastic Search服务器。
步骤:
1、服务端安装ik分词器
2、客户端指定
安装:
1)下载源码
https://github.com/medcl/elasticsearch-analysis-ik 2) maven打包
mvn install -Dmaven.test.skip=true
3)安装到es服务器
解压到es/plugins
4)配置
可选
5)重启
五、命令操作
文档的概念:
一个文档就相当于数据库一行,数据库中一行查询就是一个对象.
在es中文档内容(原始数据)就是json对象.
对文档自身进行描述叫做文档元数据.
文档包含两部分:
元数据:
描述文档的一些信息,如文档属于哪个索引库、哪个类型、文档id
_index:索引库
_type:哪个类型
_id:文档的唯一标识
_source:文档原始数据
_all:所有字段的连接字符串
原始数据:
真正存放数据的地方,json表示
CRUD:
# 添加文档
# 自动生成id
POST shopping/employee
{
"id":1,
"name":"sp",
"age":18,
"hobby":["lol","玩鸟","吃鸡"]
}
# 用自己id
PUT shopping/employee/5
{
"id":5,
"name":"ddh",
"age":70,
"hobby":["lol","玩鸟","吃鸡"]
}
#查询所有
GET _search
#查询一个
GET pethome/employee/2
#批量查询
GET pethome/employee/_mget
{
"ids":["AXTSU0iiUh5X5MckEmeH",2]
}
#最全的查询
GET pethome/employee/_search?q=age=18&sort=age:desv&from=0&size=3&_source=name
#删除特定id的文档
DELETE shopping/employee/AWynggKuBpHo_8YMV204
#修改 整体修改,先删除后添加,会丢失信息
PUT shopping/employee/1
{
"id":1,
"name":"eg"
}
#局部更新
POST shopping/employee/1/_update
{
"doc": {
"id":1,
"name":"sp"
}
}
DSL语句:
dsl主要用来进行查询,以JSON格式载入查询条件,提高可读性,主要分为两部分查询和过滤。
#查询
GET pethome/employee/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 5
}
#过滤查询
GET pethome/employee/_search
{
"query": {
"bool": {
"must": [
{"match_all": {}}
],
"filter": {
"range": {
"age": {
"gte": 10,
"lte": 50
}
}
}
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 5,
"_source": ["name","age"]
}
六、Java操作Elastic Search
导包
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
JavaAPI
public class ESTest {
String INDEX="pethome";
String TYPE="employee";
public static TransportClient getClient()throws Exception{
Settings settings= Settings.builder().put("client.transport.sniff",true).build();
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getByName("127.0.0.1"), 9300));
return client;
}
/**
* 添加文档索引
*/
@Test
public void addDoc()throws Exception{
//获取传输客户端
TransportClient client = getClient();
//获取索引写入器
IndexRequestBuilder builder = client.prepareIndex(INDEX,TYPE,"1");
//构建文档数据
HashMap<String, Object> map = new HashMap<>();
map.put("id",1);
map.put("name","ww");
map.put("age",18);
builder.setSource(map);
//执行操作
IndexResponse response = builder.get();
System.out.println(response);
//关闭
client.close();
}
/**
* 查询
* @throws Exception
*/
@Test
public void getDoc()throws Exception{
//获取客户端
TransportClient client = getClient();
System.out.println(client.prepareGet(INDEX, TYPE, "1").get().getSource());
client.close();
}
/**
* 删除文档
* @throws Exception
*/
@Test
public void delDoc()throws Exception{
//获取客户端
TransportClient client = getClient();
client.prepareDelete(INDEX,TYPE,"1").get();
client.close();
}
/**
* 更新文档
* @throws Exception
*/
@Test
public void updateDoc()throws Exception{
//获取客户端
TransportClient client = getClient();
//准备更新build
UpdateRequestBuilder builder = client.prepareUpdate(INDEX,TYPE,"1");
//构建文档数据
HashMap<String, Object> map = new HashMap<>();
map.put("id",1);
map.put("name","zs");
map.put("age",22);
builder.setDoc(map);
//提交
UpdateResponse response = builder.get();
System.out.println(response);
client.close();
}
/**
* 批量操作
* @throws Exception
*/
@Test
public void bulk()throws Exception{
//获取客户端
TransportClient client = getClient();
BulkRequestBuilder builder = client.prepareBulk();
for (int i=0;i<50;i++){
HashMap<String, Object> map = new HashMap<>();
map.put("id",i);
map.put("name","zs"+i);
map.put("age",i);
builder.add(client.prepareIndex(INDEX,TYPE,""+i).setSource(map));
}
//批量执行
BulkResponse responses = builder.get();
if (responses.hasFailures()){
System.out.println("error");
}
client.close();
}
/**
* DSL查询
* @throws Exception
*/
@Test
public void dsl()throws Exception{
//获取客户端
TransportClient client = getClient();
SearchRequestBuilder builder = client.prepareSearch(INDEX).setTypes(TYPE);
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//设置查询所有
List<QueryBuilder> must = boolQuery.must();
must.add(QueryBuilders.matchAllQuery());
//查询条件
boolQuery.filter(QueryBuilders.rangeQuery("agr").lte(20).gte(60));
//设置排序
builder.addSort("age", SortOrder.DESC);
//设置分页
builder.setFrom(0);
builder.setSize(10);
//截取字段
builder.setFetchSource(new String[]{"age","name"},null);
SearchResponse response = builder.get();
//展示内容
System.out.println("命中数:"+response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSource());
}
client.close();
}
}
``