1 分词器–练习
什么叫分词:
把一个段话 按照一定规则 拆分开
为什么分词:
便于检索
分词器放入到ES:
解压ik分词器 -->在es 在plugins目录 -->创建一个IK文件夹 -->把ik插件拷贝到ik文件下面
注意:
报错:
log [06:34:24.297] [error][status][plugin:elasticsearch@5.2.2] Status changed from red to red - [index_closed_exception] closed, with { index_uuid=“FIXWQGUxQiKjwdTR-PTRKQ” & index=".kibana" }
原因:当前路径有空格或者中文
测试 :ES怎么使用分词:
POST _analyze
{
"analyzer":"ik_smart",
"text":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
2 文档映射–认识
文档映射: 每个字段匹配为一种确定的数据类型
2.1 基本类型–默认可以设置
字符串: Text /TextField keyword StringField
数字:long int float double
布尔类型:boolean
日期类型:date
2.2 对象类型–了解
Object /Array
如果对象类型存储 – 使用字符串,存一个json字符串
2.3 ES有默认的类型
(1)当我们保存数据的时候,就给字段指定类型 (默认自带类型)
(2)我们也可以自己指定类型
删除库
创建库
设定类型
添加数据
(1)Delete shop;
(2)PUT shop;
(3)POST shop/goods/_mapping
{
"goods": {
"properties": {
"price": {
"type": "integer"
},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
}
}
}
}
(4)加入数据
put shop/goods/1
{
"price":88,
"name": "iphone8"
}
这种 缺点: 如果字段比较多,比较麻烦
(3)全局映射
步骤:
(1) 删除库
(2)创建库
(3)指定动态模板 – 不要担心,公司会根据自己的规则设定
(4)加入数据,字段类型 ,根据指定类型做相应
(5)在java创建索引 或者添加数据, 分词存起来,查询也会根据分词去查
(4)最佳实践:
① 有数据,有库 -->(建议把数据查询,保存的文档)
② 删除库
③ 创建库
④先指定动态模板 --(根据公司规则)
⑤在自定义配置规则
⑥加入数据 完成crud
3 ES集群
3.1 为什么集群:
一台服务器不够使用的时候,需要多台服务器支持, 解决 高并发,单点故障,容错
3.2 集群里面相关概念
分片: 存储内容 主分片 和从分片
node:节点 有很多类型的节点
节点属性的配置:
四种组合配置方式
(1)node.master: true node.data: true
这种组合表示这个节点即有成为主节点的资格,又存储数据。
如果某个节点被选举成为了真正的主节点,那么他还要存储数据,这样对于这个节点的压力就比较大了。ElasticSearch默认每个节点都是这样的配置,在测试环境下这样做没问题。实际工作中建议不要这样设置,因为这样相当于主节点和数据节点的角色混合到一块了。
(2)node.master: false node.data: true
这种组合表示这个节点没有成为主节点的资格,也就不参与选举,只会存储数据。
这个节点我们称为data(数据)节点。在集群中需要单独设置几个这样的节点负责存储数据,后期提供存储和查询服务。
(3)node.master: true node.data: false
这种组合表示这个节点不会存储数据,有成为主节点的资格,可以参与选举,有可能成为真正的主节点,这个节点我们称为master节点。
(4)node.master: false node.data: false
这种组合表示这个节点即不会成为主节点,也不会存储数据,这个节点的意义是作为一个client(客户端)节点,主要是针对海量请求的时候可以进行负载均衡。
3.3 搭建集群
搭建三个节点的集群
(1)拷贝三个ES 分别取名为node1 node2 node3
(2)修改配置
修改内存配置 xms xmx
配置elasticsearch.yml
# 统一的集群名
cluster.name: my-ealsticsearch
# 当前节点名
node.name: node-1
# 对外暴露端口使外网访问
network.host: 127.0.0.1
# 对外暴露端口
http.port: 9201
#集群间通讯端口号
transport.tcp.port: 9301
#集群的ip集合,可指定端口,默认为9300
discovery.zen.ping.unicast.hosts: [“127.0.0.1:9301”,”127.0.0.1:9302”,”127.0.0.1:9303”]
(3)配置跨域
(4)启动node1 node2 node3
(5)启动head
创建索引 .指定分片 (如果没有分配从分片,磁盘占用率太高,)
可以设置
cluster.routing.allocation.disk.threshold_enabled: false
4查询
GET crm/student/_search
{
"query": {
"bool": {
"must": [
{"matchall": { }}
],
"filter": {
"range": {
"age": {
"gte": 100,
"lte": 800
}
}
}
},
"from": 0,
"size": 3,
"_source": ["name", "age"],
"sort": [{"age": "asc"}]
}
5.ES java API
ES对Java提供一套操作索引库的工具包,即Java API。所有的ES操作都使用Client对象执行。
ES的Maven引入
org.elasticsearch.client
transport
5.2.2
org.apache.logging.log4j
log4j-api
2.7
org.apache.logging.log4j
log4j-core
2.7
6.2连接ES获取Client对象
方式一: 把每台服务的ip 端口配上
TransportClient 利用transport模块远程连接一个ES集群。它并不加入到集群中,只是简单的获得一个或者多个初始化的transport地址,并以轮询的方式与这些地址进行通信。
// on startup
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(“host1”), 9300))
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(“host2”), 9300));
// on shutdown
client.close();
方式二:通过集群名称来查找
注意,如果你有一个与 ES集群不同的集群,你可以设置机器的名字。
Settings settings = Settings.builder()
.put(“cluster.name”, “myClusterName”).build();
TransportClient client = new PreBuiltTransportClient(settings);
//添加地址到client中
方式三: 推荐使用方式
你可以设置client.transport.sniff为true来使客户端去嗅探整个集群的状态,把集群中其它机器的ip地址加到客户端中,这样做的好处是一般你不用手动设置集群里所有集群的ip到连接客户端,它会自动帮你添加,并且自动发现新加入集群的机器。代码实例如下:
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))
测试代码
package cn.itsource;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
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.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EsTest {
public 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 test() throws Exception{
//得到client
TransportClient client = getClient();
IndexRequestBuilder builder = client.prepareIndex("zh", "user", "1");
Map mp = new HashMap();
mp.put("name","张三");
mp.put("age",23);
builder.setSource(mp);
IndexResponse indexResponse = builder.get();
System.out.println(indexResponse);
client.close();
}
// 查询
@Test
public void testSearch() throws Exception {
TransportClient client = getClient();
System.out.println(client.prepareGet("zh", "user", "1").get().getSource());
}
// 修改
@Test
public void testUpdate() throws Exception {
TransportClient client = getClient();
IndexRequest indexRequest = new IndexRequest("zh", "user", "1");
HashMap hashMap = new HashMap();
hashMap.put("name", "zs");
hashMap.put("age",13 );
UpdateRequest updateRequest = new UpdateRequest("zh", "user", "1").doc(hashMap).upsert(indexRequest);
client.update(updateRequest).get();
client.close();
}
//删除
@Test
public void testDel() throws Exception{
TransportClient client = getClient();
client.prepareDelete("zh","user","1").get();
client.close();
}
//批量操作
@Test
public void testBulk() throws Exception {
TransportClient client = getClient();
BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
for(int i=1;i<50;i++){
Map mp = new HashMap();
mp.put("name","tt"+i);
mp.put("age",18+i);
bulkRequestBuilder.add(client.prepareIndex("shoppings","goods",""+i).setSource(mp));
BulkResponse response = bulkRequestBuilder.get();
if (response.hasFailures()){
System.out.println("出错了");
}
}
}
//DSL查询
@Test
public void testDSL() throws Exception{
TransportClient client = getClient();
SearchRequestBuilder builder = client.prepareSearch("shoppings").setTypes("goods");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> must = boolQueryBuilder.must();
must.add(QueryBuilders.matchAllQuery());
//过滤年龄大于18小鱼60
boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gt(18).lt(60));
builder.setQuery(boolQueryBuilder);
//分页起始
builder.setFrom(0);
builder.setSize(5);
//排序
builder.addSort("age", SortOrder.DESC);
builder.setFetchSource(new String[]{"name","age"},null);
//取值
SearchResponse searchResponse = builder.get();
//拿到查询结果
SearchHits hits = searchResponse.getHits();
//命中数据
SearchHit[] hits1 = hits.getHits();
for (SearchHit e : hits1) {
System.out.println(e.getSource());
}
}
}