ES(分布式全文搜索引擎)

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;2PUT shop;3POST 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());
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值