elasticsearch学习一-ES入门

1 ES简介

1.1 ES技术栈

The Elastic Stack, 包括 Elasticsearch、Kibana、Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。Elaticsearch,简称为ES, ES是一个开源的高扩展的分布式全文搜索引擎,是整个Elastic Stack技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。

1.2 全文搜索引擎

Google,百度类的网站搜索,它们都是根据网页中的关键字生成索引,我们在搜索的时候输入关键字,它们会将该关键字即索引匹配到的所有网页返回;还有常见的项目中应用日志的搜索等等。对于这些非结构化的数据文本,关系型数据库搜索不是能很好的支持。

一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。进行全文检索需要扫描整个表,如果数据量大的话即使对SQL的语法优化,也收效甚微。建立了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。这里说到的全文搜索引擎指的是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

1.3 正排索引vs倒排索引

正排索引一般指关系型数据库中的索引,把不同的数据存放在不同的字段中,通过索引字段查找数据。

倒排索引的思想是把数据中的关键词提取出来,转换为关键词到数据的映射

1.4 数据格式

Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档。为了方便大家理解,我们将Elasticsearch里存储文档数据和关系型数据库MySQL存储数据的概念进行一个类比ES里的Index可以看做一个库,而Types相当于表,Documents则相当于表的行。这里Types的概念已经被逐渐弱化,Elasticsearch 6.X中,一个index下已经只能包含一个type,Elasticsearch 7.X中, Type的概念已经被删除了。

 

2 入门使用

2.1 索引操作

2.1.1 创建索引

PUT:http://localhost:9200/user

response:

{
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "user"
}

2.1.2 查询索引

GET:http://localhost:9200/user

response:

{
    "user": {
        "aliases": {},
        "mappings": {},
        "settings": {
            "index": {
                "creation_date": "1618108925731",
                "number_of_shards": "1",
                "number_of_replicas": "1",
                "uuid": "U8Fc9YEHTQSHRVZjm1VoDQ",
                "version": {
                    "created": "7080099"
                },
                "provided_name": "user"
            }
        }
    }
}

查询全部索引

GET:http://localhost:9200/_cat/indices?v

response:

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   user  U8Fc9YEHTQSHRVZjm1VoDQ   1   1          0            0       208b           208b

表头

含义

health

当前服务器健康状态:

green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)

status

索引打开、关闭状态

index

索引名

uuid

索引统一编号

pri

主分片数量

rep

副本数量

docs.count

可用文档数量

docs.deleted

文档删除状态(逻辑删除)

store.size

主分片和副分片整体占空间大小

pri.store.size

主分片占空间大小

2.1.3 删除索引

DELETE:http://localhost:9200/user

2.2 文档操作

2.2.1 创建文档

POST:http://127.0.0.1:9200/user/_doc

request

{
    "name":"汤姆",
    "age":20,
    "hobby":"唱歌,足球,篮球,爬山"
}

response

{
    "_index": "user",
    "_type": "_doc",
    "_id": "ABQIv3gB_sQQDSsOlaVw",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

表头

含义

_index

索引

_type

文档

_id

主键,随机生成

_version

版本

_result

操作结果,包括created、updated、deleted

_shards

total:分片总数,successful:分片成功,failed:分片失败

_seq_no

 

自定义id创建文档

POST:http://127.0.0.1:9200/user/_doc/1

request

{
    "name":"杰瑞",
    "age":21,
    "hobby":"唱歌,跳舞,看电影,追剧"
}

response

{
    "_index": "user",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 1,
    "_primary_term": 1
}

2.2.2 查询文档

根据id查询

GET:http://127.0.0.1:9200/user/_doc/1

response

{
    "_index": "user",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "_seq_no": 1,
    "_primary_term": 1,
    "found": true,
    "_source": {
        "name": "杰瑞",
        "age": 21,
        "hobby": "唱歌,跳舞,看电影,追剧"
    }
}

全部查询

GET:http://127.0.0.1:9200/user/_search

{
    "took": 69,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "user",
                "_type": "_doc",
                "_id": "ABQIv3gB_sQQDSsOlaVw",
                "_score": 1.0,
                "_source": {
                    "name": "汤姆",
                    "age": 20,
                    "hobby": "唱歌,足球,篮球,爬山"
                }
            },
            {
                "_index": "user",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "杰瑞",
                    "age": 21,
                    "hobby": "唱歌,跳舞,看电影,追剧"
                }
            }
        ]
    }
}

2.2.3 修改数据

全量修改

POST:http://127.0.0.1:9200/user/_doc/1

request

{
    "name":"托尼",
    "age":22,
    "hobby":"唱歌,跳舞,看电影,追剧"
}

response

{
    "_index": "user",
    "_type": "_doc",
    "_id": "1",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 2,
    "_primary_term": 1
}

version版本加1

局部修改

POST:http://localhost:9200/user/_update/1

request

{
    "doc": {
        "name":"派克"
    }
}

response

{
    "_index": "user",
    "_type": "_doc",
    "_id": "1",
    "_version": 3,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 3,
    "_primary_term": 1
}

2.2.4 删除数据

DELETE:http://127.0.0.1:9200/user/_doc/1

2.3 条件查询

2.3.1 根据字段查询

GET:http://127.0.0.1:9200/user/_search

request

{
    "query":{
        "match":{
            "name":"派克"
        }
    }
}

response

{
    "took": 68,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.3862942,
        "hits": [
            {
                "_index": "user",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.3862942,
                "_source": {
                    "name": "派克",
                    "age": 22,
                    "hobby": "唱歌,跳舞,看电影,追剧"
                }
            }
        ]
    }
}

2.3.2 分页查询

request

{
    "query": {
        "match_all": {}
    },
    "from": 1, // 从第几条查询
    "size": 1, // 查询数量
    "_source": [
        "name",
        "age"
    ], // 字段过滤,如果没有则查询所有字段
    "sort": {
        "age": "desc"
    } // 按照年龄降序
}

response

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "user",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "派克",
                    "age": 22
                }
            }
        ]
    }
}

2.3.3 条件查询

查询姓名是汤姆或派克的用户

request

{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "name": "汤姆"
                    }
                },
                {
                    "match": {
                        "name": "派克"
                    }
                }
            ]
        }
    }
}

查询姓名是汤姆并且喜欢唱歌的用户

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "name": "汤姆"
                    }
                },
                {
                    "match": {
                        "hobby": "唱歌"
                    }
                }
            ]
        }
    }
}

2.3.4 范围查询

查询年龄超过21岁的用户

request

{
    "query": {
        "bool": {
            "filter": {
                "range": {
                    "age": {
                        "gt": 21
                    }
                }
            }
        }
    }
}

2.3.5 关键字精确查询

match匹配会根据查询参数进行分词,然后查询。如果不想对查询参数分词则需要使用match_phrase关键字

request

{
    "query": {
        "match_phrase": {
            "name": "汤派"
        }
    }
}

这里不能查出数据。如果改为match,则会对汤派进行分词,查询出两条数据

2.3.6 高亮显示

对查询结果name字段高亮显示

request

{
    "query": {
        "match": {
            "name": "汤"
        }
    },
    "highlight": {
        "fields": {
            "name": {}
        }
    }
}

response

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.6931471,
        "hits": [
            {
                "_index": "user",
                "_type": "_doc",
                "_id": "ABQIv3gB_sQQDSsOlaVw",
                "_score": 0.6931471,
                "_source": {
                    "name": "汤姆",
                    "age": 20,
                    "hobby": "唱歌,足球,篮球,爬山"
                },
                "highlight": {
                    "name": [
                        "<em>汤</em>姆"
                    ]
                }
            }
        ]
    }
}

2.3.7 聚合查询

根据年龄分组

request

{
    "aggs": { // 聚合操作
        "age_group": { // 名称,随意起名
            "terms": { // 分组
                "field": "age" // 分组字段
            }
        }
    },
    "size": 0 // 不要原始数据
}

response

{
    "took": 8,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 4,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "age_group": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": 22,
                    "doc_count": 2
                },
                {
                    "key": 20,
                    "doc_count": 1
                },
                {
                    "key": 21,
                    "doc_count": 1
                }
            ]
        }
    }
}

求年龄平均值

request

{
    "aggs": { // 操作
        "age_avg": { // 名称,随意起名
            "avg": { // 求平均值
                "field": "age" // 统计字段
            }
        }
    },
    "size": 0 // 不要原始数据
}

response

{
    "took": 5,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 4,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "age_avg": {
            "value": 21.25
        }
    }
}

2.4 映射操作

2.4.1 创建映射

PUT:http://127.0.0.1:9200/student/_mapping

request

{
    "properties": {
        "name": {
            "type": "text",
            "index": true
        },
        "sex": {
            "type": "text",
            "index": false
        },
        "age": {
            "type": "long",
            "index": false
        }
    }
}

映射数据说明

字段名:任意填写,下面指定许多属性,例如:title、subtitle、images、price

type:类型,Elasticsearch中支持的数据类型非常丰富,说几个关键的

String类型,又分两种:

text:可分词

keyword:不可分词,数据会作为完整字段进行匹配

Numerical:数值类型,分两类

基本数据类型:long、integer、short、byte、double、float、half_float

浮点数的高精度类型:scaled_float

Date:日期类型

Array:数组类型

Object:对象

index:是否索引,默认为true,也就是说你不进行任何配置,所有字段都会被索引。

true:字段会被索引,则可以用来进行搜索

false:字段不会被索引,不能用来搜索

store:是否将数据进行独立存储,默认为false

原始的文本会存储在_source里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true即可,获取独立存储的字段要比从_source中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。

analyzer:分词器,这里的ik_max_word即使用ik分词器

2.4.2 查看映射

GET:http://127.0.0.1:9200/student/_mapping

response

{
    "student": {
        "mappings": {
            "properties": {
                "age": {
                    "type": "long",
                    "index": false
                },
                "name": {
                    "type": "text"
                },
                "sex": {
                    "type": "text",
                    "index": false
                }
            }
        }
    }
}

2.4.3 索引映射关联

PUT:http://127.0.0.1:9200/student

request

{
    "settings": {},
    "mappings": {
        "properties": {
            "name": {
                "type": "text",
                "index": true
            },
            "sex": {
                "type": "text",
                "index": false
            },
            "age": {
                "type": "long",
                "index": false
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值