睁眼写BUG,闭眼改BUG。

ES 入门

2019.06.14

ElasticSearch 入门学习笔记

ElasticSearch 是一个实时的分布式搜索分析引擎.

ElasticSearch 是一个开源的搜索引擎.

一个分布式的实时文档存储.

一个分布式实时分析搜索引擎.

ElasticSearch 致力于隐藏分布式系统的复杂性

安装 ElasticSearch

Docker 安装

# 搜索镜像
docker search elasticsearch
# 下载(版本号 可以在 docker hub 里找)
docker pull elasticsearch:版本号
# 没有配置镜像加速, 可以使用以下命令
docker pull registry.docker-cn.com/library/elasticsearch
# 检查
docker images
# 运行ES(elasticsearch 启动默认占用2g堆内存所以需要限制)
docker run -e ES_JAVA_OPTS="-Xms256m -Xms256m" -d -p 9201:9200 -p 9301:9300 --name ES01 image_id
# (与外部通信默认使用9200,分布式各个节点通信用9300)

Docker-Compose 运行 ES

ps: 找个文件夹放docker-compose.yml配置文件等

例如:

​ /usr/local/docker

# 新建文件放ES配置
mkdir elasticsearch
# 新建docker-compose.yml
vi docker-compser.yml
# 在docker-compose.yml放入以下内容

docker-composer.yml

version: '3'
services:
  elasticsearch:
    image: elasticsearch:5.4.3
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms256m -Xms256m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata1:/usr/local/docker/elasticsearch/data # 配置数据卷
    ports:
      - "9200:9200"
    networks:
      - esnet

volumes:
  esdata1:
    driver: local # 声明esdata1这个数据卷
    
networks:
  esnet:

注意: 缩进不是一个TAB 而是两个字符(空格两次)

附: Docker 重命名镜像/容器名称

重命名镜像

docker tag imageID name:tag
# 列如:
docker tag 11ec6c70d8b6 halo:0.4
# docker tag 镜像ID 新名字:版本号
# 旧镜像会被保留
# 重命名镜像名好处就是: 使用docker-compose不用输入很长的名字
# 重命名后 被保留的原名镜像千万不要删, 因为它们是一个ID 删了后果... 

重命名容器

docker rename 原容器名 新容器名
# 遗憾的是 用docker-compose 重启后 名字又回去了 很长

注意

区分容器镜像的区别

测试

访问 域名/Ip:9200 得到一组Json数据

注意:虚拟机或服务器太小是运行不起来的, 可以下载低版本

安装 Kibana

Docker 安装

kibana 是一个开源的分析和可视化平台,

用户和Elasticsearch一起工作

可以用来搜索查看并和存在Elasticsearch索引中的数据进行交互

docker pull kibana:5.4.3
# 版本要和Elasticsearch一致
# 运行 端口是 5601
docker run -it -p 5601:5601 -e SERVER_HOST="0.0.0.0" -e ELASTICSEARCH_URL="http://ES的IP:9200" --name kibana01 kibana:5.4.3

Docker Compose 运行 Kibana

docker-compose.yml

version: '3'
# 管理的服务
services:
  elasticsearch:
    # 指定镜像
    image: elasticsearch:5.4.3
    # 限制内存
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms256m -Xms256m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      # 目录映射
      - esdata1:/usr/local/docker/elasticsearch/data # 配置数据卷
    # 端口
    ports:
      # 端口映射
      - "9200:9200"
    networks:
      - esnet

  kibana:
    image: kibana:5.4.3
    environment:
      SERVER_NAME: kibana
      ELASTICSEARCH_URL: http://www.iscolt.com:9200
    ports:
      - "5601:5601"

volumes:
  esdata1:
    driver: local # 声明esdata1这个数据卷

networks:
  esnet:

索引

Elasticsearch 和关系型数据库对比

SQLES
DatabasesIndices
TablesTypes
Rows(行)Documents
Columns(列)Fields

Elasticsearch 可以包含多个索引(数据库), 每个索引可以包含多个类型(表), 每个类型可以包含多个文档(行), 每个文档包含多个字段(列).

索引就像类似数据库,

索引里有文档

文档中有字段

Postman 示列

说明:

  1. 利用Postman工具发送请求
  2. postman中选择 Body 在里面输入数据

要求:

  1. 创建一个索引 名: megacorp (名字而已)
  2. 创建员工文档 类型(名): employee
  3. 加入id1的员工

操作

# 请求
PUT /megacorp/employee/1
# 传的数据
{
	"first_name" : "John",
	"last_name" : "Smith",
	"age" : 25,
	"about" : "I love to go rock climbing",
	"interests" : [ "sports", "music"]
}

结果

{
    "_index": "megacorp",
    "_type": "employee",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "created": true
}

Kibana 操作示列

添加索引后, 点击Dev Tools 输入即可

kibana其他功能, 查看文档

操作

PUT	/megacorp/employee/4 
{				
	"first_name" : "文艺",
	"last_name"	: "马1",
	"age"	: 21,
	"about"	: "我喜欢学习IT技术",
	"interests": [ "音乐", "跑步" ] 
}

结果

{
  "_index": "megacorp",
  "_type": "employee",
  "_id": "6",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": true
}

ps:

​ 感觉和postman是差不多的, kibana 更加好用, 简洁

​ kibana的dev tools 实际上就是识别你的代码,

​ 得到请求方式, 请求接口, 请求数据

搜索

查询字符串(query string)搜索

GET /索引/类型/_search?q=last_name:Smith

这种操作 中文无法搜索

使用 DSL 语句查询

DSL(特定领域语言) 以JSON请求体的形式

GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "last_name" : "马"
        }
    }
}

复杂的搜索

找Smith, 年龄大于30

  1. 添加过滤器
GET /megacorp/employee/_search
{
    "query" : {
        "filtered" : {
            "filter" : {
                "range" : {
                    "age" : {"gt" : 30} 
                }
            },
            "query" : {
                "match" : {
                     "last_name" : "Smith"
                }
            }
        }
    }
}

不知道是版本问题, 还是其他原因, 查不了

报错, 没有 filtered 找个方法

下面的方法可以实现

GET /megacorp/employee/_search
{
    "query" : {
        "bool" : {
            "must" : {
                "match" : {
                     "last_name" : "Smith"
                }
            },
            "filter" : {
                "range" : {
                    "age" : {"gt" : 30} 
                }
            }
        }
    }
}

区间搜索

GET megacorp/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "age": {
              "gte": 25,
              "lte": 30
            }
          }
        }
      ]
    }
  }
}

搜索 25到30岁的人

全文搜索

GET	/megacorp/employee/_search 
{
    "query" : {
        "match" : {
            "about" : "IT"
        }
    }
}

短语搜索

GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "IT"
        }
    }
}

高亮搜索

GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}

返回示列

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.53484553,
    "hits": [
      {
        "_index": "megacorp",
        "_type": "employee",
        "_id": "1",
        "_score": 0.53484553,
        "_source": {
          "first_name": "John",
          "last_name": "Smith",
          "age": 25,
          "about": "I love to go rock climbing",
          "interests": [
            "sports",
            "music"
          ]
        },
        "highlight": {
          "about": [
            "I love to go <em>rock</em> <em>climbing</em>"
          ]
        }
      }
    ]
  }
}

分析

例如:

​ 分析员工最大的共同点是什么(兴趣爱好)

GET	/megacorp/employee/_search 
{		
    "aggs" :	{
        "all_interests" :	{
            "terms" :	{ "field":	"interests" }
        }
    }
}

似乎不太有用, 先了解, 用分析会消耗大量内存

其他操作示列

官方文档