ES安装及使用说明
1.下载ES安装包
官方下载地址:https://www.elastic.co/downloads/elasticsearch
在window环境下,ES 5.2.2版本为例,下载对应的ZIP文件
2.解压文件夹,在bin目录下打开elasticsearch.bat
注意:启动es会吃很多内存,内存不够需要修改就找到config文件目录下的jvm.options,打开找到(Xms:代表最小2G,Xmx代表最大2G),修改最小为200m(兆),运行内存会变小。
3.验证
访问:http://localhost:9200
看到上图信息,你的ES集群已经启动并且正常运行.
Restful
介绍:
Restful是一种面向资源的架构风格,可以简单理解为:使用URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作。
使用Restful的好处:
透明性,暴露资源存在。
充分利用 HTTP 协议本身语义。
无状态,这点非常重要。在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,不用考虑当前状态,极大的降低了复杂度。
HTTP 本身提供了丰富的内容协商手段,无论是缓存,还是资源修改的乐观并发控制,都可以以业务无关的中间件来实现。
辅助管理工具Kibana5
1.Kibana5.2.2下载地址:https://www.elastic.co/downloads/kibana
2.解压并启动Kibana5 : bin\kibana.bat(注意:使用Kibana5要联网,不然一直出现warning错误)
启动成功界面:
3.默认访问地址:http://localhost:5601
进入界面代表成功
Discover:可视化查询分析器
Visualize:统计分析图表
Dashboard:自定义主面板(添加图表)
Timelion:Timelion是一个kibana时间序列展示组件(暂时不用)
Dev Tools :Console(同CURL/POSTER,操作ES代码工具,代码提示,很方便)
Management:管理索引库(index)、已保存的搜索和可视化结果(save objects)、设置 kibana 服务器属性。
ES数据管理
什么是ES中的文档:
ES是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在ES中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。
ES使用Javascript对象符号(JavaScript Object Notation),也就是JSON,作为文档序列化格式。
基本语法-增删改查:
//基本语法-增删改查
#创建数据库(必须用put创建)
PUT crm3
#创建表中数据,不写id会默认给id
POST crm3/user/1
{
"id":1,
"name":"kd",
"age":21
}
#查询
GET crm3/user/1
#删除
DELETE crm/user/1
#修改(PUT,POST都可以修改,先删后改,版本依次递增 )
PUT crm3/user/1
{
"id":1,
"name":"kd",
"age":22
}
//文档的简单查询
#查询,只返回文档内容,不要元数据
GET crm3/user/_source
#局部更新文档,没有会添加新的
POST crm3/user/1/_update
{
"doc": {
"id":1,
"name":"ks",
"age":22,
"birthday":"1997-02-22"
}
}
#脚本更新文档
POST crm3/user/1/_update
{
"script": "ctx._source.age+=5"
}
#批量操作bulk API
#create当文档不存在时创建之。
#index创建新文档或替换已有文档。
#update局部更新文档。
#delete删除一个文档。
POST _bulk
{ "delete": { "_index": "itsource", "_type": "employee", "_id": "123" }}
{ "create": { "_index": "itsource", "_type": "blog", "_id": "123" }}
{ "title": "我发布的博客" }
{ "index": { "_index": "itsource", "_type": "blog" }}
{ "title": "我的第二博客" }
#批量获取,不同索引库
GET _mget
{
"docs" : [
{
"_index" : "crm",
"_type" : "user",
"_id" : 3
},
{
"_index" : "itsource",
"_type" : "employee",
"_id" : 1,
"_source": ["name","age"]
}
]
}
#同一个索引库的同一个类型下
GET crm/user/_mget
{
"ids":["1","2"]
}
#查所有
GET _search
#查某一个的所有
GET crm/_search
#查某张表的所有
GET crm/user/_search
#添加多条
POST crm/user
{
"id":1,
"name":"ks",
"age":22
}
#分页搜索,每页显示5个结果
GET _search?size=5
#查询字符串搜索
GET crm/user/_search?q=age:21
#批量插入数据
POST crm2/user/13
{
"id":1,
"name":"kd",
"age":33,
"gj":"china"
}
DSL查询与过滤
什么是DSL查询:
由ES提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。
案例:
#查询名字(kd),国家(gj),年龄(20-30),页码(1),每页显示数据条数(4),排序方式(根据年龄大小降序)
GET crm2/user/_search
{
"query": {
"bool": {
"must": [
{"match": {
"name":"kd"
}}
],
"filter":[
{
"term": {"gj":"china"}
},{
"range":{
"age": {
"gte": 20,
"lt": 30
}
}
}
]
}
},
"size":4,
"from":1,
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
IK分词器
介绍:
中文分词器,同lucene一样,在使用中文全文检索前,需要集成IK分词器。
1.下载 IK分词器
ES的IK分词器插件源码地址:https://github.com/medcl/elasticsearch-analysis-ik
2.解压并将解压后的文件放入ElasticSearch目录下的plugins文件夹下
3.重启ES
4.测试分词器
#IK分词器测试
#ik_smart: 会做最粗粒度的拆分
#ik_max_word: 会将文本做最细粒度的拆分
POST _analyze
{
"analyzer":"ik_smart",
"text":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
注意:IK分词器有两种类型,分别是ik_smart分词器和ik_max_word分词器。
ik_smart: 会做最粗粒度的拆分
ik_max_word: 会将文本做最细粒度的拆分
//文档映射Mapper
#查看索引类型的映射配置
GET crm/user/_mapping
#针对单个类型的映射配置方式
POST crm/user/_mapping
{
"user": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
}
}
}
}
DELETE crm
PUT crm
POST crm/user/1
{
"id":1,
"name":"kd",
"age":22
}
#利用全局模板覆盖自带的默认模板
PUT _template/global_template
{
"template": "*",
"settings": { "number_of_shards": 1 },
"mappings": {
"_default_": {
"_all": {
"enabled": false
},
"dynamic_templates": [
{
"string_as_text": {
"match_mapping_type": "string",
"match": "*_txt",
"mapping": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
{
"string_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}}
POST crm/user/25
{
"id":1,
"name_txt":"kd",
"age":22,
"birthday":"1997-01-01"
}
#查看索引类型的映射配置
GET crm/user/_mapping
Java API
什么是Java API:
ES对Java提供一套操作索引库的工具包,即Java API。所有的ES操作都使用Client对象执行。
注入所需要的依赖包
我们使用eclipse创建maven项目
pom.xml
<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>es</groupId>
<artifactId>es</artifactId>
<version>0.0.1-SNAPSHOT</version>
<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>
<!-- junit测试包 -->
<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>
</project>
ES获取Client对象
// 接ES获取Client对象
public TransportClient getClient() throws Exception {
// on startup
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
return client;
}
测试CRUD及批量操作
package es;
//测试需要的包
import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequestBuilder;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;
public class EStest {
// 接ES获取Client对象
public TransportClient getClient() throws Exception {
// on startup
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
return client;
}
// 添加
@Test
public void testAdd() throws Exception {
// 构建请求对象,crm:索引库 user:表名 1:文档ID
IndexRequestBuilder prepareIndex = getClient().prepareIndex("crm", "user", "1");
// 添加数据
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("name", "kd");
map.put("age", 21);
map.put("gj", "china");
// 响应对象,发送数据给客户端
IndexResponse indexResponse = prepareIndex.setSource(map).get();
System.out.println(indexResponse);
// 关闭资源
getClient().close();
}
// 删除
@Test
public void testDelete() throws Exception {
// 构建请求对象,crm:索引库 user:表名 1:文档ID
DeleteRequestBuilder prepareDelete = getClient().prepareDelete("crm", "user", "1");
// 响应对象,发送数据给客户端
DeleteResponse deleteResponse = prepareDelete.get();
System.out.println(deleteResponse);
// 关闭资源
getClient().close();
}
// 修改,和Kibana5不同,必须要有数据才能修改,没有添加功能
@Test
public void testUpdate() throws Exception {
// 构建请求对象,crm:索引库 user:表名 1:文档ID
UpdateRequestBuilder prepareUpdate = getClient().prepareUpdate("crm", "user", "1");
// 添加数据
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("name", "kd");
map.put("age", 23);
map.put("gj", "china");
// 响应对象,发送数据给客户端
// 局部更新,注意:在APIjar包里,java认为局部更新很重要
UpdateResponse updateResponse = prepareUpdate.setDoc(map).get();
System.out.println(updateResponse);
}
// 查找,根据id查找
@Test
public void testGet() throws Exception {
// 构建请求对象,crm:索引库 user:表名 1:文档ID
GetRequestBuilder prepareGet = getClient().prepareGet("crm", "user", "1");
// 响应对象,发送数据给客户端
GetResponse getResponse = prepareGet.get();
System.out.println(getResponse.getSource());
// 关闭资源
getClient().close();
}
// 添加修改,没有就添加,有就修改
@Test
public void testUpdateOrSave() throws Exception {
// 添加数据
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("name", "kd");
map.put("age", 33);
map.put("gj", "china");
// 创建索引
IndexRequest indexRequest = new IndexRequest("crm", "user", "1").source(map);
// 跟新操作
UpdateRequest updateRequest = new UpdateRequest("crm", "user", "1").doc(map).upsert(indexRequest);
getClient().update(updateRequest).get();
// 关闭资源
getClient().close();
}
// 批量操作(这里批量添加)
@Test
public void testBulk() throws Exception {
// 构建批量对象
BulkRequestBuilder bulkRequest = getClient().prepareBulk();
// 批量添加数据
for (int i = 0; i < 10; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("name", "kd" + i);
map.put("age", i + 18);
map.put("gj", "china");
bulkRequest.add(getClient().prepareIndex("crm", "vip", 1 + "").setSource(map));
}
// ES执行兵获取结果
BulkResponse bulkResponse = bulkRequest.get();
// 错误处理
if (bulkResponse.hasFailures()) {
System.out.println("出错了!");
}
// 关闭资源
getClient().close();
}
}
测试搜索功能:
//搜索,查询名字(kd),国家(gj),年龄(20-30),页码(1),每页显示数据条数(2),排序方式(根据年龄大小降序)
@Test
public void testQuery() throws Exception {
//构建排序对象
SortBuilder sortBuilder = new FieldSortBuilder("age");
sortBuilder.order(SortOrder.DESC);
//构建查询对象
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
//构建mast搜索条件
boolQueryBuilder.must(new MatchQueryBuilder("name","kd"));
//构建filter 过滤条件
List<QueryBuilder> builders = boolQueryBuilder.filter();
builders.add(new TermQueryBuilder("gj","china"));
builders.add(new RangeQueryBuilder("age").gte(20).lte(30));
//构建搜索对象
SearchResponse searchResponse = getClient().prepareSearch("crm").setTypes("user").
setFrom(0).setSize(2).addSort(sortBuilder).setQuery(boolQueryBuilder).get();
//返回结果
SearchHits searchHits = searchResponse.getHits();
System.out.println(searchHits.totalHits());
//循环
for (SearchHit searchHit : searchHits.getHits()) {
System.out.println(searchHit.getScore());
}
}