ElasticSearch经典入门学习教程和案例详解

ElasticSearch

ES即为了解决原生Lucene使用的不足,优化Lucene的调用方式,并实现了高可用的分布式集群的搜索方案.
Es的索引库是基于apache Lucene。
通过简单的 RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单
特点:
分布式的实时文件存储,每个字段都被索引并可被搜索
分布式的实时分析搜索引擎
可以扩展到上百台服务器,处理PB级结构化或非结构化数据
区别:
Solr 利用 Zookeeper 进行分布式管理,支持更多格式的数据(HTML/PDF/CSV),官方提供的功能更多在传统的搜索应用中表现好于 ES,但实时搜索效率低。
ES自身带有分布式协调管理功能,但仅支持json文件格式,本身更注重于核心功能,高级功能多有第三方插件提供,在处理实时搜索应用时效率明显高于 Solr 。

安装ES

下载es
下载地址:https://www.elastic.co/downloads/elasticsearch
下载好了只需要解压出来,只需要运行elasticsearch.bat即可
访问:http://localhost:9200/ 显示出来东西就成功了

ES交互方式

ES和所有客户端的交互都是使用JSON格式的数据.
都是基于RESETful API。
Restful是一种面向资源的架构风格,可以简单理解为:使用URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)操作。
GET 用来获取资源,
POST 用来新建资源(也可以用于更新资源),
PUT 用来更新资源,
DELETE 用来删除资源。

辅助可视化工具Kibana

下载地址:https://www.elastic.co/downloads/kibana
启动Kibana : bin\kibana.bat
Discover:可视化查询分析器
Visualize:图表
Dashboard:自定义主面板
Timelion:Timelion是一个kibana时间序列展示组件
Dev Tools :控制台
Management:管理索引库

ES的使用

_index:索引库,相等于数据库库名
_type:相等于数据库下面的表名
_id:索引
_source:文档原始数据
_all:所有字段的连接字符串


  1. PUT {index}
    比如 PUT crm
    post也有添加的效果
    在这里插入图片描述
    在这里插入图片描述
    post和put都有同样的效果
    不过在创建索引库的时候,必须使用put。
    其原理是先删除在添加

POST {index}/{type}/{id}
{
“field”:“value”
}
post和put也由修改的效果
如果在修改只要有数据的,就会修改
只需要看result的值
created 标识为 false 因为同索引、同类型下已经存在同ID的文档
在这里插入图片描述

脚本更新
使用_update
在这里插入图片描述
ctx._source指向当前被更新的文档
注意,目前的更新操作只能一次应用在一个文档上
局部更新
POST crm/user/1/_update
{
“doc”:{
“name”:“joker”,
“age”:12
}
}

DELETE {index}/{type}/{id}
删除成功
“found” : true
失败
“found” :false
但_version依旧增加了

GET {index}/{type}/{id}
查询所有
使用 _search
查询不要看元数据
使用 _source

  1. 批量操作bulk API
    create:当文档不存在时创建
    index:创建新文档或替换已有文档
    update:局部更新文档
    delete:删除一个文档
    比如:
    在这里插入图片描述
    注意:delete后不需要请求体,最后一行要有回车
    使用_mget批量获取
    在这里插入图片描述
    在同一索引库同一类型下
    在这里插入图片描述
    使用GET _search
    查询所有索引库中的所有文档
  2. 分页
    size : 每页条数
    from : 从那页开始
    GET crm/user/_search?size=2&from=1
  3. 排序
    使用sort
  4. DSL查询
    es提供的查询语言叫做DSL
    DSL事宜json请求体的形式出现。
    query:查询组
    bool:相遇where
    match:关键字匹配
    must:必须有
    filter:过滤条件
    match_all:匹配所有
    在这里插入图片描述
    multi_match :查询允许你做 match查询的基础上同时搜索多个字段
    在这里插入图片描述
    minimum_match:至少匹配个数,默认为1
    单词搜索
    term:一个单词
    在这里插入图片描述
    terms:多个单词
    在这里插入图片描述
    组合条件查询
    使用bool
    范围查询
    使用range
    在这里插入图片描述
    gt:> gte:>= lt:< lte:<=
    前匹配查询
    使用prefix
    通配符查询
    *:多个 ?:一个
    在这里插入图片描述
  5. 分词与映射
    下载:https://github.com/medcl/elasticsearch-analysis-ik
    解压出来,放到eclipse的插件文件plugins下面。
    在测试一下:
    在这里插入图片描述
    IK分词器有两种类型分别是:
    ik_smart:最粗粒度的拆分
    ik_max_word:将文本做最细粒度的拆分
    映射:
    查看映射:GET {indexName}/{typeName}/_mapping
    默认映射 默认类型
    Boolean: true or false “boolean”
    Whole number: 123 “long”
    Floating point: 123.45 “float”
    String, valid date:“2018-09-15” “date”
    String: “as r” “text”
    字段映射的常用属性:
    type:基本的数据类型
    include_in_all:是否将该字段值组合到_all中
    all : 虚拟字段,每个文档都有该字段,代表所有字段的组合信息,作用方便直接对
    store:是否存储:默认为false
    index:索引模式:analyzed (索引并分词,text默认模式), not_analyzed (索引不分词,keyword默认模式),no(不索引)
    analyzer:索引分词器:索引创建时使用的分词器
    search_analyzer:搜索分词器:搜索该字段的值时,传入的查询内容的分词器
    针对单个类型的映射:
    在这里插入图片描述
    注意:在创建索引的时候就要指定映射的类型
    针对多个类型的映射:
    在这里插入图片描述
    对象及数组类型映射
    在这里插入图片描述
    映射:
    在这里插入图片描述
    注意:Lucene不理解对象,一个lucene文档包含键值对的一个扁平化。
    在这里插入图片描述
    数组
    在这里插入图片描述
    配置:
    在这里插入图片描述
    对象数组
    在这里插入图片描述
    映射:
    在这里插入图片描述
    扁平化:
    在这里插入图片描述
    全局映射:
    可以通过默认方式和动态模板来实现。
    默认方式:default
    在这里插入图片描述
    索引下面的都继承了_default
    。没写就是默认继承了的。
    动态模板:dynamic_templates
    在这里插入图片描述
    在这里插入图片描述
    最佳实践:
    ① 配置全局动态模板映射(覆盖默认的string映射)
    ② 配置自定义字段映射(由于基本类型主要用于过滤和普通查询,因此,字段映射主要对需要全文检索的字段进行配置)
    ③ 创建、更新和删除文档
    ④ 搜索
  6. java操作ES
    准备一个项目
    导包
<dependencies>
		<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>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

连接es获取到客户端

//获取客户端
	public TransportClient getClient() throws Exception {
		// 启动客户端
		TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
		        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
	return client;
	}

增加数据

//增加
	@Test
	public void testName() throws Exception {
		//构建请求对象
		IndexRequestBuilder prepareIndex = getClient().prepareIndex("crm", "user", "1");
		//请求数据
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("id", 1);
		map.put("name", "嘻嘻");
		map.put("age", 12);
		map.put("country", "cn");
		//响应数据
		IndexResponse indexResponse = prepareIndex.setSource(map).get();
		System.out.println(indexResponse);
	}

在去kibana 控制台,查询一下添加的数据
在这里插入图片描述
在这里插入图片描述
修改数据

//修改
	@Test
	public void testName2() throws Exception {
		//构建请求对象
		UpdateRequestBuilder prepareUpdate = getClient().prepareUpdate("crm", "user", "1");
		//请求数据
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("id", 1);
		map.put("name", "嘻嘻");
		map.put("age", 20);
		map.put("country", "cn");
		//响应数据
		UpdateResponse updateResponse = prepareUpdate.setDoc(map).get();
		System.out.println(updateResponse);
	}

再去控制台查询一下。结果发现age成20了
在这里插入图片描述
删除数据

//删除
	@Test
	public void testName3() throws Exception {
		//构建请求对象
		DeleteRequestBuilder prepareDelete = getClient().prepareDelete("crm", "user", "1");
		//响应数据
		DeleteResponse deleteResponse = prepareDelete.get();
		System.out.println(deleteResponse);
	}

回到kibana控制台查询一下,结果发现已经查询不到了
在这里插入图片描述

如果有数据就修改,没数据就添加

//有就修改,没有就添加
	@Test
	public void testName4() throws Exception {
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("id", 1);
		map.put("name", "哈哈");
		map.put("age", 21);
		map.put("country", "cn");
		//创建索引
		IndexRequest indexRequest = new IndexRequest("crm", "user", "6").source(map);
		//更新操作
		UpdateRequest updateRequest = new UpdateRequest("crm", "user", "6").doc(map).upsert(indexRequest);
		//响应数据
		UpdateResponse updateResponse = getClient().update(updateRequest).get();
		System.out.println(updateResponse);
		getClient().close();
	}

再去kibana控制台查询一下,就发现数据有了,在把age改成21,运行一下,就发现数据改变了
根据id查询

//根据id查询
	@Test
	public void testName5() throws Exception {
		//构建查询对象
		GetRequestBuilder prepareGet = getClient().prepareGet("crm", "user", "6");
		//响应查询
		GetResponse getResponse = prepareGet.get();
		System.out.println(getResponse.getSource());
	}

批量操作
添加

//批量添加操作
	@Test
	public void testName6() throws Exception {
		//构建批量对象
		BulkRequestBuilder prepareBulk = getClient().prepareBulk();
		Map<String,Object> map=new HashMap<String, Object>();
		//批量添加数据
		for (int i = 0; i < 10; i++) {
			map.put("id", i);
			map.put("name", "哈哈");
			map.put("age", 21+i);
			map.put("country", "cn");
			prepareBulk.add(getClient().prepareIndex("crm", "vip", i+"").setSource(map));
		}
		//执行
		BulkResponse bulkResponse = prepareBulk.get();
		if(bulkResponse.hasFailures()){
			System.out.println("错了");
		}
	}

查询

//查询名字哈哈  中国的 年龄 [25-30] 从第一页开始  每页显示2条  根据年龄降序
	@Test
	public void testName7() throws Exception {
		//排序对象
		SortBuilder sort=new FieldSortBuilder("age");
		sort.order(SortOrder.DESC);
		BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
		//must匹配
		boolQueryBuilder.must(new MatchQueryBuilder("name", "哈哈"));
		//构建过滤条件对象
		List<QueryBuilder> filter = boolQueryBuilder.filter();
		filter.add(new TermQueryBuilder("country", "cn"));
		filter.add(new RangeQueryBuilder("age").gte(25).lte(30));
		//构建查询对象
		SearchResponse searchResponse = getClient()
				.prepareSearch("crm").setTypes("vip")
				.setSize(2).setFrom(0).addSort(sort).setQuery(boolQueryBuilder).get();
		//得到结果
		SearchHits hits = searchResponse.getHits();
		//得到总条数
		System.out.println("总条数:"+hits.getTotalHits());
		//编辑所有查询到的数据
		for (SearchHit searchHit : hits.getHits()) {
			System.out.println(searchHit.getSource());
		}
	}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值