ElasticSearch初学入门1/2

ElasticSearch

ElasticSearch是一个基于Lucene的搜索服务器,是一个分布式、高扩展、高实时的搜索与数据分析引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。官网:https://www.elastic.co/

应用场景:

搜索:海量数据的查询

日志数据分析

实时数据分析

在使用关系型数据库查询数据时存在的弊端:

例如我们在操作关系型数据库实现模糊查询时:

  1. 性能低:使用模糊查询,左边有通配符,不会走索引,会全表扫描,性能低

  2. 功能弱:如果以”华为手机“作为条件,查询不出来数据

1.1倒排索引

将文档进行分词,形成词条和id的对应的关系即为反向索引

1.2ElasticSearch存储和查询的原理

在ElasticSearch中的:

index(索引):相当于mysql的库

映射:相当于mysql 的表结构

document(文档):相当于mysql的表中的数据

ElasticSearch使用倒排索引,对文档中title进行分词:

  1. 使用“手机”作为关键字查询

    生成的倒排索引中,词条会排序,形成一颗树形结构,提升词条的查询速度

  2. 使用“华为手机”作为关键字查询

    华为:1,3

    手机:1,2,3

1.3ElasticSearch核心概念

索引(index)

ElasticSearch存储数据的地方,可以理解成关系型数据库中的数据库概念。

映射(mapping)

mapping定义了每个字段的类型、字段所使用的分词器等。相当于关系型数据库中的表结构。

文档(document)

Elasticsearch中的最小数据单元,常以json格式显示。一个document相当于关系型数据库中的一行数据。

倒排索引

一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,对应一个包含它的文档id列表。

类型(type)

一种type就像一类表。如用户表、角色表等。在Elasticsearch7.X默认type为_doc

  • ES 5.x中一个index可以有多种type。

  • ES 6.x中一个index只能有一种type。

  • ES 7.x以后,将逐步移除type这个概念,现在的操作已经不再使用,默认_doc

1.4操作ElasticSearch

#----------操作索引------------
# 创建person索引
PUT person
# 查询指定名称的索引信息
GET person
# 查询所有索引
GET _all
# 关闭索引
POST person
# 打开索引
POST person
# 删除索引
DELETE person

1.5ElasticSearch数据类型

简单数据类型

  1. 字符串

    text:会分词,不支持聚合

    keyword:不会分词,将全部内容作为一个词条,支持聚合

  2. 数值 integer、long、float、double

  3. 布尔:boolean

  4. 二进制:binary

  5. 范围类型

    integer_range, float_range, long_range, double_range, date_range

  6. 日期:date

复杂数据类型

  1. 数组:[ ] Nested: nested (for arrays of JSON objects 数组类型的JSON对象)

  2. 对象:{ } Object: object(for single JSON objects 单个JSON对象)

1.6映射操作

# 创建索引
PUT person

# 查询索引
GET person

# 给person创建映射
PUT person/_mapping
{
  "properties":{
    "name":{
      "type":"text"
    },
    "age":{
      "type":"integer"
    }
  }
}

# 只查询person索引的映射信息
GET person/_mapping

# 删除索引,不允许直接删除映射
DELETE person

# 创建索引的同时创建映射
PUT person
{
  "mappings": {
    "properties": {
      "name":{
          "type":"text"
        },
        "age":{
          "type":"integer"
        }
    }
  }
}

# 给映射添加字段,和创建映射一样
PUT person/_mapping
{
  "properties":{
    "address":{
      "type":"text"
    }
  }
}

1.7文档操作

# 添加文档,指定id
POST person/_doc/1
{
  "name":"张益达",
  "age":30,
  "address":"武汉"
}
# 添加文档,不指定id会自动生成一个id
POST person/_doc
{
  "name":"张大炮",
  "age":33,
  "address":"武汉"
}
# 查询所有文档
GET person/_search
# 查询id=1的文档
GET person/_doc/1

# 修改文档,和添加文档一样,id存在就是修改
POST person/_doc/1
{
  "name":"snake",
  "age":33,
  "address":"武汉"
}

# 删除指定id的文档
DELETE person/_doc/1

分词器

2.1分词器介绍

IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包

是一个基于Maven构建的项目

具有60万字/秒的高速处理能力

支持用户词典扩展定义

下载地址:https://github.com/medcl/elasticsearch-analysis-ik/archive/v7.4.0.zip

2.2分词器的使用

IK分词器有两种分词模式:ik_max_wordik_smart模式

ik_max_word : 会将文本做最细粒度的拆分,比如会将 “湖北省武汉市” 拆分为 “湖北省、湖北、省、武汉市、武汉、市。

#方式一ik_max_word
GET _analyze
{
  "tokenizer": "ik_max_word",
  "text": ["湖北省武汉市"]
}

ik_max_word : 分词器执行如下:

{
  "tokens" : [
    {
      "token" : "湖北省",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "湖北",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "省",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "CN_CHAR",
      "position" : 2
    },
    {
      "token" : "武汉市",
      "start_offset" : 3,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "武汉",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "市",
      "start_offset" : 5,
      "end_offset" : 6,
      "type" : "CN_CHAR",
      "position" : 5
    }
  ]
}

ik_smart 模式:会做最粗粒度的拆分,比如会将“湖北省武汉市”拆分为湖北省、武汉市。

#方式二ik_smart
GET _analyze
{
  "tokenizer": "ik_smart",
  "text": ["湖北省武汉市"]
}

ik_smart分词器执行如下:

{
  "tokens" : [
    {
      "token" : "湖北省",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "武汉市",
      "start_offset" : 3,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 1
    }
  ]
}

2.3使用分词器查询文档

关键词查询:term

关键词查询不会分析查询条件,只有当关键词和索引完全匹配时才匹配搜索

全文查询:match

全文查询会分析查询条件,先将查询条件进行分词,然后查询,求并集

数据准备

创建索引,添加映射,并指定分词器为ik分词器

# 创建新的索引和映射
PUT user
{
  "mappings": {
    "properties": {
      "name":{
        "type": "keyword"
      },
      "age":{
      	"type": "integer"
      },
      "address":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

注意:在创建映射的时候,对于text类型的字段要指定分词器,否则默认使用standard分词器,一个中文一个词。

添加文档

#如果映射中没有age自动,此处会自动创建age自动
PUT person/_doc/1
{
  "name":"张三",
  "age":20,
  "address":"北京海淀区"
}
PUT person/_doc/2
{
  "name":"李四",
  "age":21,
  "address":"北京朝阳区"
}
PUT person/_doc/3
{
  "name":"王五",
  "age":22,
  "address":"北京昌平区"
}
PUT person/_doc/4
{
  "name":"赵六",
  "age":23,
  "address":"华为5G手机"
}

查询映射

GET user/_mapping
{
  "user" : {
    "mappings" : {
      "properties" : {
        "address" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        },
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "keyword"
        }
      }
    }
  }
}

词条查询:term

查询user中匹配到"北京"两字的词条

GET user/_search
{
  "query": {
    "term": {
      "address": {
        "value": "北京"
      }
    }
  }
}

结果:可以查到“北京朝阳区”、“北京昌平区”、“北京海淀区”。如果value=“北京天安门”,那么就一个都查不到了,因为查询条件不会被分词,需要完全匹配。

全文查询:match

全文查询会分析查询条件,先将查询条件进行分词,然后查询,求并集

GET /user/_search
{
  "query": {
    "match": {
      "address":"北京天安门"
    }
  }
}

结果:可以查到“北京朝阳区”、“北京昌平区”、“北京海淀区”

springboot整合ElasticSearch见下篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值