ElasticSearch入门

一、index管理

   1.创建index

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

        语法:PUT /index_name

PUT /java2202
{
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 0
  }
}

number_of_shards -  表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力

number_of_replicas - 是为每个 primary shard分配的replica shard数,提高了ES的可用性,
如果只有一台服务器,设置为0

效果:

   2.修改index

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

        语法:PUT /index_name/_settings

PUT /java2202/_settings
{
  "number_of_replicas" : 1
}

        注意:index一旦创建,"number_of_shards"数量是不可修改的,如果有两个分支,那么有2k条数据的话,2k条数据是分给这两个库的,是根据 hash(id)%number_of_shards(将id进行hash运算得出一个数字,将数字%分支的个数,放在相对应的分支里面),那么取值的时候也是同样的操作,Get时--->hash(id)%number_of_shards,如果主分支发送改变的话,那么Get时根据hash(id)%number_of_shards,就找不到之前存的那个库,所以一旦创建不萌修改分支数量

   3.删除index

DELETE /java2202[, other_index]

二、mapping管理

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

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

   1.创建mapping

        语法:POST /index_name/type_name/_mapping

        如:

POST /java2202/course/_mapping
{
  "properties": {            #properties建表关键字
     "name": {               #name表中的字段
        "type": "text"       #type字段的类型,text文本类型
     },
     "description": {        #description表中的字段
        "type": "text"
     },
     "studymodel": {
        "type": "keyword"
     }
  }
}

         效果:

   2.查询mapping

        查询所有索引的映射:

GET /java2202/course/_mapping

   3.更新mapping

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

   4.删除mapping

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

三、document管理

   1.创建document

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

      1.1.POST语法

        此操作为 ES 自动生成 id 的新增 Document 方式。

        语法:POST /index_name/type_name/id

        如:

POST /java2202/course/1
{
  "name":"python从入门到放弃",
  "description":"人生苦短,我用Python",
  "studymodel":"201002"
}

POST /java2202/course
{
  "name":".net从入门到放弃",
  "description":".net程序员谁都不服",
  "studymodel":"201003"
}

      1.2.PUT语法

        此操作为手工指定 id 的 Document 新增方式。

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

        如:

PUT /java2202/course/2
{
  "name":"php从入门到放弃",
  "description":"php是世界上最好的语言",
  "studymodel":"201001"
}

        新增后结果解释:

{
  "_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
}

        通过head查询数据:

    2、查询document

        语法:

    GET /index_name/type_name/id

        或

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

        如:根据课程id查询文档

GET /java2202/course/1

        如:查询所有记录

GET /java2202/course/_search

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

GET /java2202/course/_search?q=name:门

        结果:

{
  "took": 1, # 执行的时长。单位毫秒
  "timed_out": false, # 是否超时
  "_shards": { # shard 相关数据
    "total": 1, # 总计多少个 shard
    "successful": 1, # 成功返回结果的 shard 数量
    "skipped": 0,
    "failed": 0
  },
  "hits": { # 搜索结果相关数据
    "total": 3, # 总计多少数据,符合搜索条件的数据数量
    "max_score": 1, # 最大相关度分数,和搜索条件的匹配度
    "hits": [# 具体的搜索结果
      {
        "_index": "java2202",# 索引名称
        "_type": "course", # 类型名称
        "_id": "1",# id 值
        "_score": 1, # 匹配度分数,本条数据匹配度分数
        "_source": { # 具体的数据内容
          "name": "php从入门到放弃",
          "description": "php是世界上最好的语言",
          "studymodel": "201001"
        }, {
			"_index": "java2202",
			"_type": "course",
			"_id": "2",
			"_score": 0.13353139,
			"_source": {
				"name": "php从入门到放弃",
				"description": "php是世界上最好的语言",
				"studymodel": "201001"
			}
		}, {
			"_index": "java2202",
			"_type": "course",
			"_id": "6ljFCnIBp91f7uS8FkjS",
			"_score": 0.13353139,
			"_source": {
				"name": ".net从入门到放弃",
				"description": ".net程序员谁都不服",
				"studymodel": "201003"
			}
		}
	 ]
  }
}

   3、删除Document

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

        语法:DELETE /index_name/type_name/id

        如:

DELETE /java2202/course/3

        结果:

{
  "_index": "java2202",
  "_type": "course",
  "_id": "2",
  "_version": 2,
  "result": "deleted",
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 3,
  "_primary_term": 1
}

四.ES读写过程

        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主分片数量。

        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。

五、中文分词器

   1.Lucene自带中文分词器

      StandardAnalyzer:

                单字分词:就是按照中文一个字一个字地进行分词。如:“我爱中国”, 效果:“我”、“爱”、“中”、“国”。

      CJKAnalyzer:

                二分法分词:按两个字进行切分。如:“我是中国人”,效果:“我是”、“是中”、“中国”“国人”。

      上边两个分词器无法满足需求

      SmartChineseAnalyzer:

              对中文支持较好,但扩展性差,扩展词库和禁用词库等不好处理   

   2.第三方中文分析器

        paoding: 庖丁解牛最新版在 https://code.google.com/p/paoding/ 中最多支持Lucene 3.0,且最新提交的代码在 2008-06-03,在svn中最新也是2010年提交,已经过时,不予考虑。

        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.安装IK分词器

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

        下载IK分词器:(Github地址:GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary.

        1、下载zip:

         2、配置ik分词器

                ①解压elasticsearch-analysis-ik-6.2.3.zip压缩包

                ② 进入到加压后的目录修改配置文件/elasticsearch-analysis-ik-6.2.3/elasticsearch/config

配置:main.dic(扩展词典)    IKAnalyzer.cfg.xml(ik词典)    stopword.dic(停用词典)这三个文件
main.dic(扩展词典)和IKAnalyzer.cfg.xml(ik词典)时可以自定义词汇得

注意:stopword.dic(停用词典) 和 main.dic(扩展词典) 如果自定义中文词汇这两个文件编码设置为UTF-8

配置:IKAnalyzer.cfg.xml文件将扩展词典和停用词典配置进去
		
        <!--用户可以在这里配置自己的扩展字典 -->
		<entry key="ext_dict">main.dic</entry>
		 <!--用户可以在这里配置自己的扩展停止词字典-->
		<entry key="ext_stopwords">stopword.dic</entry>

配置之后:
分词器会对扩展词典里面的配置进行分词比如: 奥里给 这个之前不是词语,那么在main.dic(扩展词典)配置了之后奥里给就是分词了
比如:在stopword.dic(停用词典)里面配置的词汇,分词器将对其不进行分词比如 的 地 得 ...那么分词列表里面将没有配置得哪些词汇,搜索得话也搜不到 

        3、上传ik配置文件

                切换到/elasticsearch-analysis-ik-6.2.3目录下将/elasticsearch文件夹改名为ik(也可以不改名)上传到linux上面/elasticsearch-6.2.3/plugins目录下,重启es

        4、测试分词效果:

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

        5、两种分词模式

                ik分词器有两种分词模式:ik_max_word和ik_smart模式

           1、ik_max_word

会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民大会堂、人民、共和国、大会堂、大会、会堂等词语。

            2、ik_smart

会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。

六、field详细介绍

上边章节安装了ik分词器,如何在索引和搜索时去使用ik分词器呢?如何指定field的类型?比如日期类型、数值类型等

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

 

   1.field的属性介绍

        1.type:

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

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

         2.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"    #检索时
 }

       3.index:

        通过index属性指定是否索引 默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到。 但是也有一些内容不需要索引,比如:商品图片地址只被用来展示图片,不进行搜索图片,此时可以将index设置 为false。 删除索引,重新创建映射,将pic的index设置为false,尝试根据pic去搜索,结果搜索不到数据

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

        4.source:

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

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

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

同样,可以通过excludes参数排除某些字段:
POST /java2202/course/_mapping
{
  "_source": {
    "excludes":["description"]
  }
}

七、常用field类型

   1.text文本字段

        例如:

        1、创建新映射:

POST /java2202/course/_mapping
{
  "_source": {
    "excludes":["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
      }
  }   
}

        2、插入文档:

POST /java2202/course/1
{
  "name":"python从入门到放弃",
  "description":"人生苦短,我用Python",
  "pic":"250.jpg"
}

        3、查询测试:

GET /java2202/course/_search?q=name:放弃
GET /java2202/course/_search?q=description:人生
GET /java2202/course/_search?q=pic:250.jpg

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

   2.keyword关键字字段

上边介绍的text文本字段在映射时要设置分词器,keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段往索引目录写时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。

        例如:

        1、更改映射:

POST /java2202/course/_mapping
{
 	"properties": {
       "studymodel":{
          "type":"keyword"
       }
 	}
}

         2、插入文档:

PUT /java2202/course/2
{
 "name": "java编程基础",
 "description": "java语言是世界第一编程语言",
 "pic":"250.jpg",
 "studymodel": "2010年01月"
}

        3、根据name查询文档:

GET /java2202/course/_search?q=studymodel:2010年01月

        name是keyword类型,所以查询方式是精确查询。

  3.date日期类型

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

          例如:   

        1、设置允许date字段存储年月日时分秒、年月日及毫秒三种格式。

POST /java2202/course/_mapping
{
	"properties": {
       "timestamp": {
         "type":   "date",
         "format": "yyyy-MM-dd"
       }
     }
}

        2、插入文档

PUT /java2202/course/3
{
"name": "spring开发基础",
"description": "spring 在java领域非常流行,java程序员都在用。",
"studymodel": "201001",
 "pic":"250.jpg",
 "timestamp":"2018-07-04 18:28:58"
}

   4.Numeric类型

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

        例如:

        1、更新已有映射:

POST /java2202/course/_mapping
{
	"properties": {
	"price": {
        "type": "float"
     }
  }
} 

        2、插入文档

PUT /java2202/course/3
{
 "name": "spring开发基础",
 "description": "spring 在java领域非常流行,java程序员都在用。",
 "studymodel": "201001",
 "pic":"250.jpg",
 "price":38.6
}

八、field属性的设置标

属性标准
type分词是否头意义
index是否搜索
source是否展示
analyzerik_max_word
search_analyzerik_smart
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值