文章目录
一安装es
ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索。
环境:jdk1.8,node,
官网下载,解压即可
目录 cd /Users/sunjinglei/es/elasticsearch-7.8.1
启动 bin/elasticsearch
http://localhost:9200
安装可视化插件 前端环境
https://github.com/mobz/elasticsearch-head
Running with built in server
-
git clone git://github.com/mobz/elasticsearch-head.git
-
cd elasticsearch-head
-
npm install
-
npm run start
-
open
http://localhost:9100/
#关闭权限验证
# elastic/config/elasticsearch.yml
xpack.ml.enabled: false
#跨域
http.cors.enabled: true
http.cors.allow-origin: "*"
二安装Kibana
Kibana 是一个开源分析和可视化平台,旨在可视化操作 Elasticsearch 。Kibana可以用来搜索,查看和与存储在 Elasticsearch 索引中的数据进行交互。可以轻松地进行高级数据分析,并可在各种图表,表格和地图中显示数据。
Kibana 可以轻松理解海量数据。其简单的基于浏览器的界面使您能够快速创建和共享动态仪表板,实时显示 Elasticsearch 查询的更改。
ELK
cd /Users/sunjinglei/es/kibana-7.8.1-darwin-x86_64
bin/kibana
http://localhost:5601
配置文件yml汉化 zh_CN
三ES核心概念
倒排索引
3.1 Node 与 Cluster
Elastic 是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。
单个 Elastic 实例称为一个节点(node)。一组节点构成一个集群(cluster)。
3.2 Index
Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。
所以,Elastic 数据管理的顶层单位就叫做 Index(索引)。它是单个数据库的同义词。每个 Index (即数据库)的名字必须是小写。
3.3 Document
面向文档
Index 里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。
Document 使用 JSON 格式表示,下面是一个例子。
{ "user": "xiaohon", "title": "工程师", "desc": "java开发" }
同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。
3.4 Type
Document 可以分组,比如weather
这个 Index 里面,可以按城市分组(北京和上海),也可以按气候分组(晴天和雨天)。这种分组就叫做 Type,它是虚拟的逻辑分组,用来过滤 Document。
不同的 Type 应该有相似的结构(schema),举例来说,id
字段不能在这个组是字符串,在另一个组是数值。这是与关系型数据库的表的一个区别。性质完全不同的数据(比如products
和logs
)应该存成两个 Index,而不是一个 Index 里面的两个 Type(虽然可以做到)。
根据规划,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type。
3.5 新建和删除 Index
新建 Index,可以直接向 Elastic 服务器发出 PUT 请求。下面的例子是新建一个名叫weather
的 Index。
PUT /索引名/类型名/文档id { 请求体 }
服务器返回一个 JSON 对象,里面的acknowledged
字段表示操作成功。
{ "acknowledged":true, "shards_acknowledged":true }
然后,我们发出 DELETE 请求,删除这个 Index。
DELETE /weather
四IK分词器插件
下载 https://github.com/medcl/elasticsearch-analysis-ik
解压后放到plugins目录下,重启elastic,打印日志会显示加载到了插件,版本要和版本对应才可以使用
dic文件—配置分词
然后,新建一个 Index,指定需要分词的字段。这一步根据数据结构而异,下面的命令只针对本文。基本上,凡是需要搜索的中文字段,都要单独设置一下。
PUT /accounts
{
"mappings": {
"person": {
"properties": {
"user": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}'
上面代码中,首先新建一个名称为accounts
的 Index,里面有一个名称为person
的 Type。person
有三个字段
- user
- title
- desc
这三个字段都是中文,而且类型都是文本(text),所以需要指定中文分词器,不能使用默认的英文分词器。
Elastic 的分词器称为 analyzer。我们对每个字段指定分词器。
"user": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" }
上面代码中,analyzer
是字段文本的分词器,search_analyzer
是搜索词的分词器。ik_max_word
分词器是插件ik
提供的,可以对文本进行最大数量的分词。
ik_max_word 和 ik_smart 什么区别?
ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。
GET _analyze
{
"analyzer": "ik_max_word",//ik_smart
"text": ""
}
ik分词器 配置IKAnalyzer.cfg.xml文件。建立.dic文档
五数据操作 rest风格
索引的操作
创建一个索引
put /索引名/**类型名**/文档id type弃用,默认_doc
{
}
ElasticSearch相关的数据类型:
- 字符串类型:text、keyword
- 数值类型:long、integer、short、byte、doule、float、half float、scaled float
- 日期类型:date
- 布尔值类型:boolean
- 二进制类型:binary
- 等等…
_cat/ 看es信息
PUT覆盖修改.造成数据的丢失 状态update
现在的方法:
POST /test1/_doc/1/_update
{
"doc":{
"name":"王"
}
}
删除索引
DELETE操作和GET操作一样,后面的目标精确到文档就删除文档信息,精确到索引就删除索引信息。
文档的操作
基本操作
添加数据、
获取数据、
更新数据 推荐post 、 put
复杂操作 --搜索
简单搜索 GET 通过id查询
简单的条件查询 精确匹配。keyword整体
GET /book-index/_doc/_search?q=name:美人鱼
GET 索引名/类型名/_search?q=字段名:字段值
复杂查询:
排序,分页,高亮,模糊查询,精准查询
_score 多条的匹配度
查询参数体为
hits 索引和文档的信息,查询结果总数,查询出来的具体文档
两个条件,只要某个字段_source
GET /book-index/_doc/_search
{
"query":{
"match":{
"name":"美人"
}
},
"_source":["name"],
"sort":[
{
"age":{
"order":"desc"
}
}
]
}
From size 分页
布尔值查询 must should must_not
过滤查询filter
匹配多个条件查询 空格分隔
精确匹配term
高亮查询highlight
服务器返回的 JSON 对象,会给出 Index、Type、Id、Version 等信息。
新增记录的时候,也可以不指定 Id,这时要改成 POST 请求。
POST /accounts/person { "user": "李四", "title": "工程师", "desc": "系统管理" }'
上面代码中,向/accounts/person
发出一个 POST 请求,添加一个记录。这时,服务器返回的 JSON 对象里面,_id
字段就是一个随机字符串。
{ "_index":"accounts", "_type":"person", "_id":"AV3qGfrC6jMbsbXb6k1p", "_version":1, "result":"created", "_shards":{"total":2,"successful":1,"failed":0}, "created":true }
注意,如果没有先创建 Index(这个例子是accounts
),直接执行上面的命令,Elastic 也不会报错,而是直接生成指定的 Index。所以,打字的时候要小心,不要写错 Index 的名称。
5.2 查看记录
向/Index/Type/Id
发出 GET 请求,就可以查看这条记录。
GET /accounts/person/1?pretty=true
上面代码请求查看/accounts/person/1
这条记录,URL 的参数pretty=true
表示以易读的格式返回。
返回的数据中,found
字段表示查询成功,_source
字段返回原始记录。
{ "_index" : "accounts", "_type" : "person", "_id" : "1", "_version" : 1, "found" : true, "_source" : { "user" : "张三", "title" : "工程师", "desc" : "数据库管理" } }
如果 Id 不正确,就查不到数据,found
字段就是false
。
GET /weather/beijing/abc?pretty=true' { "_index" : "accounts", "_type" : "person", "_id" : "abc", "found" : false }
5.3 删除记录
删除记录就是发出 DELETE 请求。
DELETE /accounts/person/1
5.4 更新记录
更新记录就是使用 PUT 请求,重新发送一次数据。
PUT /accounts/person/1 { "user" : "张三", "title" : "工程师", "desc" : "数据库管理,软件开发" }' { "_index":"accounts", "_type":"person", "_id":"1", "_version":2, "result":"updated", "_shards":{"total":2,"successful":1,"failed":0}, "created":false }
上面代码中,我们将原始数据从"数据库管理"改成"数据库管理,软件开发"。 返回结果里面,有几个字段发生了变化。
"_version" : 2, "result" : "updated", "created" : false
可以看到,记录的 Id 没变,但是版本(version)从1
变成2
,操作类型(result)从created
变成updated
,created
字段变成false
,因为这次不是新建记录。
六数据查询
6.1 返回所有记录
使用 GET 方法,直接请求/Index/Type/_search
,就会返回所有记录。
GET /accounts/person/_search { "took":2, "timed_out":false, "_shards":{"total":5,"successful":5,"failed":0}, "hits":{ "total":2, "max_score":1.0, "hits":[ { "_index":"accounts", "_type":"person", "_id":"AV3qGfrC6jMbsbXb6k1p", "_score":1.0, "_source": { "user": "李四", "title": "工程师", "desc": "系统管理" } }, { "_index":"accounts", "_type":"person", "_id":"1", "_score":1.0, "_source": { "user" : "张三", "title" : "工程师", "desc" : "数据库管理,软件开发" } } ] } }
上面代码中,返回结果的 took
字段表示该操作的耗时(单位为毫秒),timed_out
字段表示是否超时,hits
字段表示命中的记录,里面子字段的含义如下。
total
:返回记录数,本例是2条。max_score
:最高的匹配程度,本例是1.0
。hits
:返回的记录组成的数组。
返回的记录中,每条记录都有一个_score
字段,表示匹配的程序,默认是按照这个字段降序排列。
6.2 全文搜索
Elastic 的查询非常特别,使用自己的查询语法,要求 GET 请求带有数据体。
GET /accounts/person/_search { "query" : { "match" : { "desc" : "软件" } } }
上面代码使用 Match 查询,指定的匹配条件是desc
字段里面包含"软件"这个词。返回结果如下。
{ "took":3, "timed_out":false, "_shards":{"total":5,"successful":5,"failed":0}, "hits":{ "total":1, "max_score":0.28582606, "hits":[ { "_index":"accounts", "_type":"person", "_id":"1", "_score":0.28582606, "_source": { "user" : "张三", "title" : "工程师", "desc" : "数据库管理,软件开发" } } ] } }
Elastic 默认一次返回10条结果,可以通过size
字段改变这个设置。
$ curl 'localhost:9200/accounts/person/_search' -d ' { "query" : { "match" : { "desc" : "管理" }}, "size": 1 }'
上面代码指定,每次只返回一条结果。
还可以通过from
字段,指定位移。
$ curl 'localhost:9200/accounts/person/_search' -d ' { "query" : { "match" : { "desc" : "管理" }}, "from": 1, "size": 1 }'
上面代码指定,从位置1开始(默认是从位置0开始),只返回一条结果。
6.3 逻辑运算
如果有多个搜索关键字, Elastic 认为它们是or
关系。
GET /accounts/person/_search { "query" : { "match" : { "desc" : "软件 系统" }} }
上面代码搜索的是软件 or 系统
。
如果要执行多个关键词的and
搜索,必须使用布尔查询。
$ curl 'localhost:9200/accounts/person/_search' -d ' { "query": { "bool": { "must": [ { "match": { "desc": "软件" } }, { "match": { "desc": "系统" } } ] } } }'
七ppt内容
-
term查询(精准查询)term是ES中的精准查询,不会参与ES分词查询,terms 查询是term的扩展,可以支持多个vlaue匹配,只需要一个匹配就可以了
-
math查询(分词匹配查询)match查询是按ES分词的倒排表进行查询,而keyword不会被分词,match的需要跟keyword的完全匹配可以。可以用于一般性的匹配查询。match
match_all match_phrase -
fuzzy查询(模糊查询)fuzzy查询可以用于纠正去拼写的问题
-
wildcard(通配符查询) wildcard(通配符查询)
-
bool查询(布尔查询)bool查询本身没有查询功能,而是基于逻辑值使用前面几种查询方式进行组合查询。
prefix 、 wildcard 和 regexp 查询是基于词操作的,如果用它们来查询 analyzed 字段,它们会检查字段里面的每个词,而不是将字段作为整体来处理。
比方说包含 “Quick brown fox” (快速的棕色狐狸)的 title 字段会生成词: quick 、 brown 和 fox 。
会匹配以下这个查询:
{ “regexp”: { “title”: “br.*” }}
但是不会匹配以下两个查询:
{ “regexp”: { “title”: “Qu." }}
{ “regexp”: { “title”: "quick br” }}
-
词频/逆向文档频率(TF/IDF)
当匹配到一组文档后,需要根据相关度排序这些文档,不是所有的文档都包含所有词,有些词比其他的词更重要。一个文档的相关度评分部分取决于每个查询词在文档中的 权重
词频:
逆向文档频率:词在集合所有文档里出现的频率是多少?频次越高,权重 越低
文档长度归一值:字段的长度是多少? 字段越短,字段的权重 越高
-
相同的文章,查询的评分不同
由于每个shard是一个独立的lucene 实例,所以TF/IDF也是独立计算的,每个分片的文章数量不同
如果两个相同内容落在了不同分片上,完全可能给出不同的评分
所以确保每个分片上有足够多的文章来减少评分在这种差异上的干扰 -
Index Boost 索引层面修改相关性
-
negative 修改文档相关性
-
function_score 自定义评分
-
脚本
八参考链接
- ElasticSearch 官方手册
- A Practical Introduction to Elasticsearch
- http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html
zookeeper环境
% docker search zookeeper 查看所有镜像
% docker pull zookeeper 拉取官方的镜像
% docker images
docker inspect 6ad6cb039dfa 查看镜像详情
docker run -d -p 2181:2181 --name zookeeper --restart always 6ad6cb039dfa 启动镜像
docker run --name=zookeeper -p 2181:2181 --restart always -d zookeeper:latest
$ docker ps // 查看所有正在运行容器
$ docker stop containerId // containerId 是容器的ID
$ docker ps -a // 查看所有容器 $ docker ps -a -q // 查看所有容器ID
$ docker stop $(docker ps -a -q) // stop停止所有容器
$ docker rm $(docker ps -a -q) // remove删除所有容器
$ docker exec -it zookeeper bash
$ ./bin/zkServer.sh status //来查看节点的状态
$ zkCli.sh //开启客户端
安装kafka
1、拉镜像 docker pull wurstmeister/kafka
2、启动kafka镜像
docker run --name kafka -p 9092:9092 --link zookeeper:zookeeper --env KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 --env KAFKA_ADVERTISED_HOST_NAME=127.0.0.1 --env KAFKA_ADVERTISED_PORT=9092 --restart always -d wurstmeister/kafka:latest
3、验证kafka是否可以使用
3.1、进入容器
$ docker exec -it kafka bash
3.2、进入 /opt/kafka_2.13-2.6.0/bin 目录下
$ cd /opt/kafka_2.13-2.6.0/bin
3.3、运行kafka生产者发送消息
$ ./kafka-console-producer.sh --broker-list localhost:9092 --topic sun
发送消息
> {"datas":[{"channel":"","metric":"temperature","producer":"ijinus","sn":"IJA0101-00002245","time":"1543207156000","value":"80"}],"ver":"1.0"}
3.4、运行kafka消费者接收消息
$ ./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic sun --from-beginning
启动成功
![kafka启动](https://gitee.com/qiaojiangl/git-img/raw/master/kafka启动.png)
测试(一)
- 在浏览器中输入地址:http://localhost:5601 使用dev-tools,它具有autocomplete的功能
- 建立一个索引和文档。创建一个叫做twitter的索引(index),并插入一个文档(document)
![创建索引](https://gitee.com/qiaojiangl/git-img/raw/master/创建索引.png)
成功地创建了一个叫做twitter的index(可以通过设置禁止自动创建索引)
![自己创建索引](https://gitee.com/qiaojiangl/git-img/raw/master/自己创建索引.png)
PUT twitter/_doc/1
{
"user": "GB",
"uid": 1,
"city": "Beijing",
"province": "Beijing",
"country": "China"
}
PUT twitter/_doc/1
{
"user": "GB",
"uid": 1,
"name": "hong"
}
PUT twitter/_doc/2
{
"user": "GB",
"uid": 1,
"city": "shandong",
"province": "shandong",
"country": "China"
}
POST twitter/_doc/1
{
"user": "GB",
"uid": 1,
"city": "Shenzhen",
"province": "Guangdong",
"country": "China"
}
GET twitter/_doc/1
GET /_mapping?pretty=true
PUT weather
DELETE weather
GET twitter/_doc/1/_source
GET twitter/_doc/1?_source=city,age,province
GET _mget
{
"docs": [
{
"_index": "twitter",
"_id": 1
},
{
"_index": "twitter",
"_id": 2
}
]
}
GET _mget
{
"docs": [
{
"_index": "twitter",
"_id": 1,
"_source":["age", "city"]
},
{
"_index": "twitter",
"_id": 2,
"_source":["province", "address"]
}
]
}
GET twitter/_doc/_mget
{
"ids": ["1", "2"]
}
数据爬取
数据来源:数据库,消息队列,爬虫
jsoup包,解析网页,tika包爬音乐视频
需要学习基本的网络编程
ik插件放置路径
mulu