elasticsearch_dsl

一. ES快速入门 ES作为一个索引及搜索服务,对外提供丰富的REST接口,快速入门部分的实例使用kibana来测试,目的是对ES的使用方法及流程有个初步的认识。 1.1 idex管理 1.1.1 创建index库 索引库 。包含若干相似结构的 Document 数据,相当于数据库的database。 语法:put

一. ES快速入门

         ES作为一个索引及搜索服务,对外提供丰富的REST接口,快速入门部分的实例使用kibana来测试,目的是对ES的使用方法及流程有个初步的认识。        

1.1 idex管理

1.1.1 创建index库

索引库。包含若干相似结构的 Document 数据,相当于数据库的database。

语法:put /index_name

  •  如:

PUT /java06
{
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 1
  }
}

  • number_of_shards - 表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力
  • number_of_replicas - 是为每个 primary shard分配的replica shard数,提高了ES的可用性如果只有一台机器,设置为0 
  • 效果(当前是head客户端展示的):

 1.1.2 修改index

注意:索引一旦创建,primary shard 数量不可变化,可以改变replica shard 数量。

语法:put /index_name/_settings

  •  如:

PUT /java06/_settings
{
  "number_of_replicas" : 5
}

1.1.3 删除index

语法: DELETE /index_name[, other_index]

1.2 mapping管理

        映射,创建映射就是向索引库中创建field(类型、是否索引、是否存储等特性)的过程,下边是document和field与关系数据库的概念的类比:

elasticsearch关系数据库
index(索引库)database(数据库)
type(类型)table(表)
document(文档)row(记录)
field(域)column(字段)

  注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES6.x 版本之后,type概念被弱化ES官方将在ES7.0版本中彻底删除type

1.2.1 创建mapping

语法: POST /index_name/type_name/_mapping

  • 如:

POST /java06/class/_mapping
{
  "properties": {
     "name": {
        "type": "text"
     },
     "sex": {
        "type": "text"
     },
     "age": {
        "type": "interge"
     }
  }

1.2.2 查询mapping

查询所有索引的映射:

语法: GET /index_name/type_name/_mapping

 1.2.3 修改mapping

  • 映射创建成功可以添加新字段,已有字段不允许更新。

1.2.4 删除mapping

  • 通过删除索引来删除映射。

1.3 document管理

1.3.1 创建document

ES中的文档相当于MySQL数据库表中的记录。

1.3.1.1 POST语法

语法: POST /index_name/type_name/id

POST /java06/class/1
{
  "name":"张红",
  "sex":"女",
  "age":"19"
}

POST /java06/class
{
  "name":"张三",
  "sex":"男",
  "age":18
}

1.3.1.2 PUT语法

此操作为手工指定 id 的 Document 新增方式。当前没有此条记录的时候相当于新建

语法:PUT/index_name/type_name/id{field_name:field_value}  

  • 如:

PUT /java06/course/1
{
  "name":"张红1",
  "sex":"女",
  "age":"22"

  • 结果:

{
  "_index": "test_index", 新增的 document 在什么 index 中,
  "_type": "my_type", 新增的 document 在 index 中的哪一个 type 中。
  "_id": "1", 指定的 id 是多少
  "_version": 1, document 的版本是多少,版本从 1 开始递增,每次写操作都会+1
  "result": "created", 本次操作的结果,created 创建,updated 修改,deleted 删除
  "_shards": { 分片信息
      "total": 2, 分片数量只提示 primary shard
      "successful": 1, 数据 document 一定只存放在 index 中的某一个 primary shard 中
      "failed": 0
  },
  "_seq_no": 0, 
  "_primary_term": 1

 1.3.2 查询document

语法: GET /index_name/type_name/id 

    或: GET /index_name/type_name/_search?q=field_name:field_value   

根据课程id查询文档:

        GET /java06/class/1

查询所有记录:

        GET /java06/class/_search

查询名称中包括php 关键字的的记录:

        GET /java06/course/_search?q=name:张

1.3.3 删除 document

        ES 中执行删除操作时,ES先标记Document为deleted状态,而不是直接物理删除。当ES 存储空间不足或工作空闲时,才会执行物理删除操作,标记为deleted状态的数据不会被查询搜索到(ES 中删除 index ,也是标记。后续才会执行物理删除。所有的标记动作都是为了NRT(近实时)实现)

语法: DELETE /index_name/type_name/id 

  • 如:

 DELETE /java06/class/1

1.4 ES读写过程

1.4.1 documnet routing(数据路由)

        当客户端创建document的时候,es需要确定这个document放在该index哪个shard上,这个过程就是document routing。

  • 路由过程:

路由算法:shard = hash(5) %number_of_primary_shards

  id:document的_id,可能是手动指定,也可能是自动生成,决定一个document在哪个shard上

  number_of_primary_shards主分片數量。

1.4.2 为什么primary shard数量不可变?

        假如我们的集群在初始化的时候有5个primary shard,我们往里边加入一个document id=5,假如hash(5)=23,这时该document 将被加入 (shard=23%5=3)P3这个分片上。如果随后我们给es集群添加一个primary shard ,此时就有6个primary shard,当我们GET id=5 ,这条数据的时候,es会计算该请求的路由信息找到存储他的 primary shard(shard=23%6=5) ,根据计算结果定位到P5分片上。而我们的数据在P3上。所以es集群无法添加primary shard,但是可以扩展replicas shard。         

二. luke查看ES的逻辑结构

2.1 luke是什么?

在这里插入图片描述

  • Luke是一个用于Lucene搜索引擎的,方便开发和诊断的第三方工具,它可以访问现有Lucene的索引,并允许您显示和修改。
  • Luke是一个方便宜的开发和诊断工具,它能访问Lucene建立好的索引同时也允许以如下的一些方式展示和修改内容:

2.2 安装

官方下载地址https://github.com/DmitryKey/luke/releases下载对应版本即可

2.3 解压运行 luke.bat

  • 5.0.0以上版本(点击luke.bat 即可启动Luke)

2.4  测试

 2.5 luke查看ES的逻辑结构

  • 拷贝elasticsearch-6.2.3(es路径下的)/data到windows

  • 双击luke.bat,启动luke

  • 使用luke打开data\nodes\0\indices路径

三. IK分词器

3.1 测试分词器 

       在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。

测试当前索引库使用的分词器:

POST /_analyze
{
  "text":"测试分词器,后边是测试内容:spring cloud实战"
}

  • 结果如下:

会发现分词的效果将“测试”这个词拆分成两个单字“测”和“试”,这是因为当前索引库使用的分词器对中文就是单字分词。

3.2 中文分词器

3.2.1 Lucene自带中文分词器

  • StandardAnalyzer:单字分词:就是按照中文一个字一个字地进行分词
  • CJKAnalyzer:二分法分词:按两个字进行切分
  • SmartChineseAnalyzer:对中文支持较好,但扩展性差,扩展词库和禁用词库等不好处理

3.2.2 第三方中文分析器

  • IK-analyzer

        最新版在https://code.google.com/p/ik-analyzer/上,支持Lucene 4.10从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词 歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。 但是也就是2012年12月后没有在更新。

3.3 安装IK分词器

使用IK分词器可以实现对中文分词的效果

下载链接https://github.com/medcl/elasticsearch-analysis-ik

3.3.1 下载zip:

 3.3.2 解压安装

将解压的文件拷贝到ES安装目录的plugins下的ik(重命名)目录下,重启es

 

 3.3.3 测试分词效果:

POST /_analyze
{
  "text":"中华人民共和国人民大会堂",
  "analyzer":"ik_smart"
}

3.4 两种分词模式

IK提供了两个分词算法:ik_smartik_max_word

其中ik_smart为最少切分,ik_max_word为最细粒度划分

3.5 自定义词库

iK分词器自带的main.dic的文件为扩展词典,stopword.dic为停用词典。

  •  修改配置文件:IKAnalyzer.cfg.xml

 之后就可以通过修改main.dic文件内容实现自定义词库了

四. field详细介绍

ES6.2核心的字段类型如下:

 4.1 field的属性介绍

4.1.1 type

  • 通过type属性指定field的类型

"name":{    
       "type":"text"
}

4.1.2 analyzer

  • 通过analyzer属性指定分词模式

 "name": {
                  "type": "text",
                  "analyzer":"ik_max_word"
   }

        上边指定了analyzer是指在索引和搜索都使用ik_max_word,如果单独想定义搜索时使用的分词器则可以通过 search_analyzer属性。

        对于ik分词器建议是索引时使用ik_max_word将搜索内容进行细粒度分词,搜索时使用ik_smart提高搜索精确性。

"name": {
                  "type": "text",
                  "analyzer":"ik_max_word",#生成索引目录时
                  "search_analyzer":"ik_smart"#检索时
 }

4.2.1 index

        通过index属性指定是否索引。 默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到。 

"pic": {
         "type":"text",           
       "index":false
}

4.3.1 source

        如果某个字段内容非常多,业务里面只需要能对该字段进行搜索,比如:商品描述。查看文档内容会再次到mysql或者hbase中取数据,把大字段的内容存在Elasticsearch中只会增大索引,这一点文档数量越大结果越明显,如果一条文档节省几KB,放大到亿万级的量结果也是非常可观的。

  •  如果只想存储某几个字段的原始值到Elasticsearch 可以通过incudes参数来设置,在mapping中的设置如下:

POST /java06/course/_mapping
{
  "_source": {
    "includes":["description"]
  }
}

  • 可以通过excludes参数排除某些字段

POST /java06/course/_mapping
{
  "_source": {
    "excludes":["description"]
  }

 4.2 常用field类型

4.2.1 text文本字段

例如:

  • 创建新映射:
POST /java06/course/_mapping
{
  "_source": {
    "includes":["description"]
  }  
  "properties": {   
       "name": {
           "type": "text",
           "analyzer":"ik_max_word",
           "search_analyzer":"ik_smart"
       },         
      "description": {
          "type": "text",
          "analyzer":"ik_max_word",
          "search_analyzer":"ik_smart"
      },
      "pic":{
          "type":"text",
          "index":false
      }
  }   
}
  • 插入文档
POST /java06/course/1
{
  "name":"python从入门到放弃",
  "description":"人生苦短,我用Python",
  "pic":"250.jpg"
}
  • 查询测试
GET /java06/course/_search?q=name:放弃
GET /java06/course/_search?q=description:人生
GET /java06/course/_search?q=pic:250.jpg

结果:name和description都支持全文检索,pic不可作为查询条件

4.2.2 keyword关键字字段

        keyword是按照整体搜索,所以创建keyword字段往索引目录写时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。

例如:

  • 更改映射
POST /java06/course/_mapping
{
 	"properties": {
       "studymodel":{
          "type":"keyword"
       }
 	}
}
  • 插入文档
PUT /java06/course/2
{
 "name": "java编程基础",
 "description": "java语言是世界第一编程语言",
 "pic":"250.jpg",
 "studymodel": "2010年01月"
}
  • 根据name查询文档
GET /java06/course/_search?q=studymodel:2010年01月

结果:name是keyword类型,所以查询方式是精确查询

4.2.3 data日期

        日期类型不用设置分词器,通常日期类型的字段用于排序。 1)format 通过format设置日期格式,多个格式使用双竖线||分隔, 每个格式都会被依次尝试, 直到找到匹配的

例如:

  • 设置允许date字段存储年月日时分秒、年月日及毫秒三种格式
POST /java06/course/_mapping
{
	"properties": {
       "timestamp": {
         "type":   "date",
         "format": "yyyy-MM-dd"
       }
     }
}
  • 插入文档
PUT /java06/course/3
{
"name": "spring开发基础",
"description": "spring 在java领域非常流行,java程序员都在用。",
"studymodel": "201001",
 "pic":"250.jpg",
 "timestamp":"2018-07-04 18:28:58"
}

4.2.4 Numeric类型

es中的数字类型经过分词(特殊)后支持排序和区间搜索

例如:

  • 更新已有映射
POST /java06/course/_mapping
{
	"properties": {
	"price": {
        "type": "float"
     }
  }
} 
  • 插入文档
PUT /java06/course/3
{
 "name": "spring开发基础",
 "description": "spring 在java领域非常流行,java程序员都在用。",
 "studymodel": "201001",
 "pic":"250.jpg",
 "price":38.6

 4.3 field属性的设置标准---根据标准设置

属性标准
type是否有意义
index是否搜索
source是否展示
知秋君
上一篇 2024-07-05 19:12
下一篇 2024-07-05 18:48

相关推荐