Elastic Search

文档 (就类似于MySQL中一个表的一条条数据)

之前说elasticsearch是面向文档的,那么意味着索引和搜索数据的最小单位是文档,elasticsearch中,文档有几个重要属性:

  • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含keyralue!
    可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的!(就是一个JSON对象,FastJson进行转换!)
  • 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段。
  • 尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整形。因为elasticsearch会保存字段和类型之间的映射及其他的设置,这种映射具体到每个映射的每种类型,这也是为什么在elasticsearch中,类型有时候也称为映射类型。

类型

类型是文档的逻輯容器,就像关系型数据库一样,表格是行的容器。类型中对于字段的定义称为映射,比如name映射为字符串类型。我们说文档是无模式的,它们不需要拥有映射中所定义的所有字段,比如新增一个字段,那么 elasticsearch是怎么做的呢?
elasticsearch会自动的将新字段加入映射,但是这个字段的不确定它是什么类型, elasticsearch就开始猜,如果这个值是18,那么elasticsearch会认为它是整形,但是 elasticsearch也可能猜不对,所以最安全的方式就是提前定义好所需要的映射,这点跟关系型数据库殊途同归了,先定义好字段,然后再使用,别整什么幺蛾子

索引

可以对比为数据库!

索引是腴射类型的容器, elasticsearch中的索引是一个非常大的文档集合,索引存储了映射类型的字段和其他设置。然后它们被存储到了各个分片上了。我们来研究下分片是如何工作的

物理设计:节点和分片如何工作
在这里插入图片描述
一个集群至少有一个节点,而一个节点就是一个 elasricsearch进程,节点可以有多个索引默认的,如果你创建索引,那么索引将会有个5个分片( primary shard又称主分片)构成的,每个主分片会有一个副本( replica shard,又称复制分片)
上图是一个有3个节点的集群,可以看到主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂掉了,数据也不至于丢失。实际上,一个分片是一个 Lucene索引,一个包含倒排索引的文件目录,倒排索引的结构使得 elasticsearch在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字。不过,等等,倒排索引是什么鬼?
在这里插入图片描述倒排索引

elasticsearch使用的是一种称为倒排索引的结构,采用 Lucene倒排索作为底层。这种结构适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。
倒排索引原理
在这里插入图片描述
索引的字段类型
字符串类型:text、keyword
数值类型:long、integer、short、byte、double、float、half float、scaled、float
日期类型:date
布尔值类型:boolean
二进制类型:binary

ik分词器

分为 最小分词器:ik_smart和最细粒度划分:ik_max_word
如果分词器中的查询字典不够用了 可以在ik的config文件夹下新建自己的字典
例如:xxxx.dic 然后在IKAnalyzer.cfg.xml 文件中 配置自己的配置文件,以;分隔开。最后重启es;
在这里插入图片描述

请求es使用restful风格,es的restful风格比较特殊
通常http协议里面的四种操作为
GET用来获取资源,
POST用来新建资源,
PUT用来更新资源,
DELETE用来删除资源。

而es中
在这里插入图片描述
常用命令

#创建索引和插入数据 也可用于强制更新数据 但是如果字段不全 没有的字段自动设为空
PUT /wudw/wudw01/1
{
  "name": "wudw",
  "age": 23,
  "gerder": "man"
}
PUT /wudw/wudw01/1
{
  "name": "wudw",
  "age": 24,
  "desc": "cool"
}
PUT /wudw/wudw01/1
{
  "name": "cmc",
  "age": 23,
  "gerder": "woman"
}
PUT /wudw/wudw01/1
{
  "name": "cmc",
  "age": 24,
  "desc": "beautiful"
}

#创建索引 设置字段类型
PUT /wudw02
{
  "mappings": 
  {
    "properties": 
    {
      "name":
      {
        "type": "text"
      },
      "age":
      {
        "type": "integer"
      },
      "birthday":
      {
        "type": "date"
      }
    }
  }
}

#获取数据
GET /wudw/wudw01/1
#获取索引类型
GET /wudw02
#查看底层信息
GET _cat/indices?v

#修改数据-------推荐------
POST /wudw/wudw01/1/_update
{"doc":{
    "name": "cmc",
  "age": 23,
  "gerder": "man"
}
}

#删除数据
DELETE /wudw/wudw01/1

# 根据条件查询用户
# 所有用户得分(权重)相同
GET wudw/wudw01/_search?q=name:wudw

#递归查询
GET /wudw/wudw01/_search
{
  "query": {
    "match": {
      "name": "wudw"
    }
  }
}
#结果过滤
GET /wudw/wudw01/_search
{
  "query": {
    "match": {
      "name": "wudw"
    }
  },
  "_source": ["name","desc"]
}
# 排序,分数消失
GET /wudw/wudw01/_search
{
  "query": {
    "match": {
      "name": "wudw"
    }
  },
  "sort": [{
    "age": {
      "order": "desc"
    }
  }]
}
# 多条件查询,must相当于and,should相当于or,must_not相当于not,结果为4条数据
GET /wudw/wudw01/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "wudw"
          }
        },
        {
          "match": {
            "name": "cmc"
          }
        }
      ]
    }
  }
}
# 分页,from和size相当于limit的两个参数
GET /wudw/wudw01/_search
{
  "query": {
    "match": {
      "name": "wudw"
    }
  },
  "sort": [{
    "age": {
      "order": "desc"
    }
  }],
  "from": 0,
  "size": 1
}
#should相当于or,结果为1条数据 
GET /wudw/wudw01/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "wudw"
          }
        },
        {
          "match": {
            "age": "23"
          }
        }
      ]
    }
  }
}

#结果为name!=wudw and age!=23的那条数据 
GET /wudw/wudw01/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "name": "wudw"
          }
        },
        {
          "match": {
            "age": "23"
          }
        }
      ]
    }
  }
}
# 过滤查询,gt和gte相当于>和>=,lt和lte相当于<和<=
GET /wudw/wudw01/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "age": {
            "gt": 23,
            "lte": 24
          }
        }
      }
    }
  }
}

# 多条件查询,用空格隔开,满足一个条件即可
GET /wudw/wudw01/_search
{
  "query": {
    "match": {
      "name": "wudw cmc"
    }
  }
}


#选出所有满足条件的
GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query": "外滩如家",
      "fields": ["name","brand"]
    }
  }
}

#精确匹配
GET /hotel/_search
{
  "query": {
    "term": {
      "city": {
        "value": "上海"
      }
    }
  }
}
#改变排名权重
GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "name": "外滩"
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "brand": "如家"
            }
          },
          "weight": 10
        }
      ],
      "boost_mode": "multiply"
    }
  }
}
#查询名字带有”如家“ 价格不高于400,在坐标31.21,121.5周围10km范围内的酒店。。。。 注意:must_not和filter不参与排名算score
GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "如家"
          }
        }
      ],
      "filter": {
        "geo_distance": {
          "distance": "10km",
          "location": {
            "lat": 31.21,
            "lon": 121.5
          }
        }
      },
      "must_not": [
        {
          "range": {
            "price": {
              "gt": 400
            }
          }
        }
      ]
    }
  }
}

#默认情况搜索字段 需要与高亮字段一致
GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query": "外滩如家",
      "fields": ["name","brand"]
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "pre_tags": "<wu>",
        "post_tags": "</wu>"
      }
      
    }
  }
}
结果:如下

在这里插入图片描述

term 查询直接通过倒排索引指定的词条进行精确查找。
text 类型会被分词器解析,keyword 类型不会被分词器解析。

es节点职责划分:
在这里插入图片描述
查询结果:
在这里插入图片描述
1. 默认hash运算 节点位置=hash(_route)%分片数量
2. 分片数量一旦创建后,不能再修改了

如果不是根据id查询呢 那就是通过路由节点将请求分发到每个节点上,最后还由路由节点汇总结果返回。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值