EsApi的demo链接:
https://gitee.com/zgr777/elastic-search-api.git
名词解释:
正排索引:
直接根据主键索引 id 查询data内容
id | data |
---|---|
111 | 我是人 |
110 | 我是中国人 |
倒排索引:
先对data分词,关联id,从而获取完整数据
keyword | id |
---|---|
我 | 111,110 |
人 | 111,110 |
中国人 | 110 |
ElasticSearch
Elastic有一条完整的产品线:Elasticsearch、Logstash、Kibana等,前面说的三个就是大家常说的ELK技术栈。
Elasticsearch官网:https://www.elastic.co/cn/products/elasticsearch
API文档地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html
Elasticsearch默认分片数为5个,并为每个分片创建一个副本
主分片可以读写
副本分片只能读
Elasticsearch具备以下特点:
- 分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心)
- Restful风格,一切API都遵循Rest原则,容易上手
- 近实时搜索,数据更新在Elasticsearch中几乎是完全同步的。
ES的默认端口:
9300:结点之间通信的端口
9200:对外开放的http端口
ES结构说明
索引库(indices)---------------------------------Database 数据库
类型(type)----------------------------------Table 数据表
文档(Document)---------------------------------Row 行
域字段(Field)--------------------------------Columns 列
映射配置(mappings)-------------------------------每个列的约束(类型、长度)
ES的读写流程
如图为一个3个分片,一个副本的es集群,主节点是node-02,主节点的作用是来管理索引的变更,而不是文档。
写流程:
1、要新增\删除一条文档,写请求负载到一个节点上(如node-01),通过文档的_id确定该文档属于分片0。
2、对分片0进行写操作,成功后,分片0同步到副本0。
3、最后反馈给节点。
读流程:
1、用户读请求访问节点01
2、节点根据文档_id,确定要读取的数据所属的分区和所有副本,然后LB到其中一个读取数据。
3、结果反馈。
ES中安装中文分词器IkAnalyzer
https://github.com/medcl/elasticsearch-analysis-ik
安装后要解压到es的plugins文件中
lucene中: StringField --不分词 textField --分词
ElasticSearch中 : keyword --不分词 text–分词(默认)
遇到的坑,在ES中做精确查询时,如果没有做mapping映射,会将该field的type转为text,并且会提供 [field] 和 [field].keyword两个字段。
Kibana的语法
详见参考文档
GET /_analyze //请求路径
{
"analyzer": "ik_max_word", //指定分词器 ik_max_word会进行细分,ik_smart会智能分词
"text": "我是中国人"
}
创建索引库
put /myIndex
创建字段映射(类型)
PUT /索引库名/_mapping/类型名称
PUT myIndex/_mapping/goods
{
"properties": {
"title": { //字段名
"type": "text",
"analyzer": "ik_max_word"
},
"images": {
"type": "keyword",
"index": "false" //是否加入索引库,默认true
},
"price": {
"type": "float"
}
}
}
查看映射
GET /myIndex/_mapping
一次创建索引库和类型
PUT /myIdex
{
"settings": {},
"mappings": {
"goods": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
新增数据
POST /myIndex/goods/
{
"title":"小米手机",
"images":"http://image.leyou.com/12479122.jpg",
"price":2699.00
}
根据Id查看数据
GET /myIndex/goods/r9c1KGMBIhaxtY5rlRKv
新增数据并自定义Id
POST /myIndex/goods/2
{
"title":"大米手机",
"images":"http://image.leyou.com/12479122.jpg",
"price":2899.00
}
修改数据,如果不存在则新增
PUT /myIndex/goods/3
{
"title":"超米手机",
"images":"http://image.leyou.com/12479122.jpg",
"price":3899.00,
"stock": 100,
"saleable":true
}
动态模板
//只指定title的映射,而其他字段为string时走动态模板的映射
PUT myIndex2
{
"mappings": {
"goods": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
}
},
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
}
查询所有match_all(会查找全部,但是只会显示十条)
GET /myIndex/_search
{
"query":{
"match_all": {}
}
}
匹配查询match
会分词进行查询,默认是or关系,需要指定and关系
GET /myIndex/_search
{
"query":{
"match":{
"title":"小米电视"
}
}
}
指定and关系
GET /goods/_search
{
"query":{
"match":{
"title":{"query":"小米电视","operator":"and"}
}
}
}
词条匹配term
term
查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串
GET /myIndex/_search
{
"query":{
"term":{
"price":2699.00
}
}
}
布尔组合(bool)
bool
把各种其它查询通过must
(与)、must_not
(非)、should
(或)的方式进行组合
must: 一定有
must_not: 一定没有
should: 可有可无
GET /heima/_search
{
"query":{
"bool":{
"must": { "match": { "title": "大米" }},
"must_not": { "match": { "title": "电视" }},
"should": { "match": { "title": "手机" }}
}
}
}
范围查询(range)
range
查询找出那些落在指定区间内的数字或者时间
//大于等于1000小于2800
GET /myIndex/_search
{
"query":{
"range": {
"price": {
"gte": 1000.0,
"lt": 2800.00
}
}
}
}
模糊查询(fuzzy)
指定查询词条与实际可以有多少偏差
GET /myIndex/_search
{
"query": {
"fuzzy": {
"title": {
"value":"appla",
"fuzziness":1 //最多与结果有1个偏差
}
}
}
}
高亮
GET /myIndex/_search
{
"query": {
"match": {
"title": "手机"
}
},
"highlight": {
"pre_tags": "<em>",
"post_tags": "</em>",
"fields": {
"title": {}
}
}
}
聚合操作
相当于分组
//对颜色分组
GET /car/_search
{
"size" : 0,
"aggs" : {
"popular_colors" : {
"terms" : {
"field" : "color"
}
}
}
}
//对颜色分组后,查看每组颜色的平均价格
GET /car/_search
{
"size" : 0,
"aggs" : {
"popular_colors" : {
"terms" : {
"field" : "color"
},
"aggs":{
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
//对颜色分组后,查看每组颜色的平均价格
GET /car/_search
{
"size" : 0,
"aggs" : {
"popular_colors" : {
"terms" : {
"field" : "color"
},
"aggs":{
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
```