时间: 2023-05-10 【学无止境】 阅读量:共701人围观
简介 Elasticsearch 是一个分布式的免费开源搜索和分析引擎,适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。
特点
1.一个分布式的实时文档存储,每个字段 可以被索引与搜索
2.一个分布式实时分析搜索引擎
3.能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据
基本数据类型
1.字符串类型:text、keyword
2.数值类型:long、integer、short、byte、double、float、half、scaled、float
3.日期类型:date
4.布尔值类型:boolean
5.二进制类型:binary
等等。
Rest 风格写法
1.PUT localhost:9200/索引名称/类型名称/文档 id 创建文档(指定文档 id)【索引类比“库”,类型类比“表”】
2.POST localhost:9200/索引名称/类型名称 创建文档(随机文档 id)
3.POST localhost:9200/索引名称/类型名称/_search 查询所有数据
4.POST localhost:9200/索引名称/类型名称/文档 id/_update 修改文档
5.GET localhost:9200/索引名称/类型名称/文档 id 通过id查询文档
6.DELETE localhost:9200/索引名称/类型名称/文档 id 删除文档
初步检索
1、_cat
GET/_cat/nodes //查看所有节点
GET/_cat/health //查看es健康状况
GET/_cat/master //查看主节点
GET/_cat/indices //查看所有索引
2、索引一个文档(保存)
//在customer索引下的external类型下保存1号数据为
PUT customer/external/1
{
"name":"John Doe"
}
PUT和POST都可以:
POST新增。如果不指定id,会自动生成id。指定id就会修改这个数据,并新增版本号。
PUT可以新增可以修改。PUT必须指定id,由于PUT需要指定id,我们一般用来做修改操作,不指定id会报错。
3、查询文档
GET customer/external/1
//结果:
{
"_index" : "customer", //索引
"_type" : "external", //类型
"_id" : "1", //记录id
"_version" : 1, //版本号
"_seq_no" : 0, //并发控制字段,每次更新就会+1,用来做乐观锁
"_primary_term" : 1, //同上,主分片重新分配,如重启,就会变化
"found" : true,
"_source" : {
"name" : "John Doe"
}
}
//可以用_seq_no和_primary_term做并发时的乐观锁
//在更新时携带当前的这两个值,后台更新时如发现这两个值已经变化了(即更新过)则会更新失败
//?if_seq_no=1&if_primary_term=1
4、更新文档
//该方法会对比原来数据,如果数据与原来一样,则什么都不做
POST customer/external/1/_update
{
"doc" : {
"name":"John Doew"
}
}
//或者 不带update则不会检查原数据,会一直更新
POST customer/external/1
{
"name":"John Doe2"
}
//或者
PUT customer/external/1
{
"name":"John Doe2"
}
//更新同时增加属性 不带update也可以
POST customer/external/1/_update
{
"doc":{"name":"Jane Doe","age":20}
}
5、删除文档&索引
//删除文档
DELETE customer/external/1
//删除索引 不能直接删除类型
DELETE customer
6、bulk批量API
POST customer/external/_bulk
{"index":{"_id":"1"}}
{"name":"John Doe"}
{"index":{"_id":"2"}}
{"name":"John Doe"}
//语法格式
{action:{metadata}}\n
{request body}\n
进阶检索
1.准备
为了测试更复杂的情况,需要将官方提供的测试数据用批量命令进行导入。
//命令是
POST bank/account/_bulk
//后跟上面的测试数据
2. 基本语法
//查询语句的典型结构
{
QUERY_NAME:{
ARGUMENT:VALUE,
ARGUMENT:VALUE,
}
}
//例子
GET bank/_search
{
//查询条件
"query": {
"match_all": {}
},
//排序方式
"sort": [
{
"account_number": "asc"
} ,
{
"balance": "desc"
}
],
//分页
"from": 0,
"size": 20,
//显示哪些信息
"_source": ["balance", "firstname"]
}
3. match
全文匹配,如果是数值类型会进行完全匹配,如果是字符串类型则会对检索条件进行分词匹配,返回的结果会按得分从高到低排列。
如果字符串类型的要匹配精确的值,可在字段后面加上.keyword
GET bank/_search
{
"query": {
"match": {
"balance": 16418
}
}
}
//查到了19条记录
GET bank/_search
{
"query": {
"match": {
"address": "Mill lane"
}
}
}
4. math_phrase
短语匹配,将需要匹配的值当成一个整体单词(不分词)进行检索。
//只能查到一条记录
GET bank/_search
{
"query": {
"match_phrase": {
"address": "Mill lane"
}
}
}
5. multi_match
多字段匹配,即多个字段匹配检索条件。
//address和city会分别与mill和movico进行匹配
GET bank/_search
{
"query": {
"multi_match": {
"query": "mill movico",
"fields": ["address","city"]
}
}
}
6. bool复合查询
GET bank/_search
{
"query": {
"bool": {
//必须满足
"must": [
{
"match": {
"gender": "M"
}
},
{
"match": {
"address": "mill"
}
}
],
//必须不是 相当于过滤器
"must_not": [
{
"match": {
"age": 28
}
}
],
//应该满足 满足了分数会相应提高,不满足不会被过滤掉
"should": [
{
"match": {
"lastname": "Hines"
}
}
]
}
}
}
7. filter
//filter就是一个过滤器.能够对查询到的结果进行过滤,且不会贡献相关性得分
GET bank/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
]
}
}
}
8. term
和match一样,匹配某个属性的值。
建议:全文检索字段用match,其他非text字段匹配用term
GET bank/_search
{
"query": {
"term": {
"balance": {
"value": 32838
}
}
}
}
//完全匹配,不能查到数据
GET bank/_search
{
"query": {
"match": {
"address.keyword": "798 Farragut"
}
}
}
//对比上面,短语匹配,能查到一条数据
GET bank/_search
{
"query": {
"match_phrase": {
"address": "798 Farragut"
}
}
}
聚合(aggregations)
聚合提供了从数据中分组和提取数据的能力。最简单的聚合方法大致等于SQL GROUP BY和SQL聚合函数。在ES中,执行搜索会返回hits(命中结果),并且同时返回聚合结果,把一个响应中的所有hits分隔开的能力。
//搜索address中包含mill的所有人的年龄分布以及平均年龄
GET bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg":{
"avg": {
"field": "age"
}
}
}
}
//返回的聚合结果为
"aggregations" : {
"ageAgg" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 38,
"doc_count" : 2
},
{
"key" : 28,
"doc_count" : 1
},
{
"key" : 32,
"doc_count" : 1
}
]
},
"ageAvg" : {
"value" : 34.0
}
}
//按照年龄聚合,并且请求这些年龄段的平均薪资
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 3
},
"aggs": {
"avgAgg": {
"avg": {
"field": "balance"
}
}
}
}
}
}
//返回的结果
"aggregations" : {
"ageAgg" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 820,
"buckets" : [
{
"key" : 31,
"doc_count" : 61,
"avgAgg" : {
"value" : 28312.918032786885
}
},
{
"key" : 39,
"doc_count" : 60,
"avgAgg" : {
"value" : 25269.583333333332
}
},
{
"key" : 26,
"doc_count" : 59,
"avgAgg" : {
"value" : 23194.813559322032
}
}
]
}
}
映射(Mapping)
映射是定义文档及其包含的字段的存储和索引方式的过程。
每个文档都是字段的集合,每个字段都有自己的 数据类型。映射数据时,您将创建一个映射定义,其中包含与文档相关的字段列表。映射定义还包括元数据字段,例如该 _source字段,用于自定义如何处理文档的关联元数据。
使用动态映射和显式映射来定义数据。每种方法都会根据您在数据旅途中的位置提供不同的好处。例如,将字段显式映射到您不想使用默认值的位置,或者获得对创建哪些字段的更大控制权。然后,您可以允许Elasticsearch动态添加其他字段。
1. 创建一个索引并且指定映射
PUT /my-index-000001
{
"mappings": {
"properties": {
"age": { "type": "integer" },
"email": { "type": "keyword" },
"name": { "type": "text" }
}
}
}
2. 在索引中添加映射
PUT /my-index-000001/_mapping
{
"properties": {
"addr": { "type": "keyword" }
}
}
3. 更新映射
不能更新映射。
4. 数据迁移
//先创建出new_twitter的正确映射
//然后使用如下方式进行数据迁移
POST _reindex [固定写法]
{
"source":{
"index": "twitter",
"type": "tweet" //如果有类型需加上
},
"dest":{
"index": "new_twitter"
}
}