这是 ElasticSearch 系列的第三篇:
第一篇:
第二篇:
第三篇:
ElasticSearch 是文档型数据库,索引(Index)定义了文档的逻辑存储和字段类型,每个索引可以包含多个文档类型,文档类型是文档的集合,文档以索引定义的逻辑存储模型,比如,指定分片和副本的数量,配置刷新频率,分配分析器等,存储在索引中的海量文档分布式存储在 ElasticSearch 集群中。
ElasticSearch 是基于 Lucene 框架的全文搜索引擎,将所有文档的信息写入到倒排索引(Inverted Index)的数据结构中,倒排索引建立的是索引中词和文档之间的映射关系,在倒排索引中,数据是面向词(Term)而不是面向文档的。
ElasticSearch 的对象模型,跟关系型数据库模型相比:
索引是由段(Segment)组成的,段不是实时更新的,这意味着,在建立索引时,一个段写入磁盘后,就不再被更新。被删除文档的信息存储在一个单独的文件中,在搜索数据时,ElasticSearch 首先从段中查询,再从查询结果中过滤被删除的文档,这意味着,段中存储 "未被删除文档" 的密度降低。多个段可以通过段合并(Segment Merge)操作把 "已删除" 的文档将从段中物理删除,将未删除的文档合并成一个新段,新段中没有 "已删除文档",因此,段合并操作能够提高索引的查找速度,但段合并是 IO 密集型的,需要消耗大量的 IO 操作。
一,创建索引
在创建索引之前,首先了解 RESTful API 的调用风格,在管理和使用 ElasticSearch 服务时,常用的 HTTP 动词有下面五个:
1,禁用自动创建索引
推荐设置:在全局配置文件 elasticsearch.yml 中,禁用自动创建索引:
- action.auto_create_index:false
2,手动创建索引
创建索引的语法是:PUT http://host:port/index_name/ + index_configuration
其中,index_name 是创建的索引的名字,indiex_configuration 是向 ElasticSearch 服务器传递的请求负载的主体,数据格式是 json,用于定义索引的配置信息:映射节(mappings)和配置节(settings)。
在创建索引时,需要精心设计索引的映射节(mappings)和配置节(settings),本例创建 blog 索引和 articles 文档类型,创建索引的语法是:
PUT http://localhost:9200/blog/
下文详细介绍 ElasticSearch 索引的配置信息
二,索引映射节(mappings)
1,索引结构
索引是由文档类型构成的,在 mappings 字段中定义索引的文档类型,示例代码中为 blog 索引定义了三个文档类型:articles,followers 和 comments
- {
- "mappings":{
- "articles":{ },
- "followers":{ },
- "comments":{ }
- }
- }
2,文档属性
文档属性定义了文档类型的共用属性,适用于文档的所有字段:
- {
- "mappings":{
- "articles":{
- "numeric_detection":false,
- "dynamic":false,
- "dynamic_date_formats":["yyyy-MM-dd hh:mm:ss", "yyyy-MM-dd" ],
- "properties":{
- "id":{},
- "title":{},
- "author":{},
- "content":{},
- "postedat":{}
- }
- }
- }
- }
三,文档的字段属性
1,字段的数据类型
字段的数据类型由字段的属性 type 指定,ElasticSearch 支持的基础数据类型主要有:
在文档类型的 properties 属性中,定义字段的 type 属性,指定字段的数据类型:
- "properties": {
- "id": {
- "type": "long"
- },
2,字段的公共属性
3,字符串类型常用的其他属性
分析器 (analyzer) 属性,可以引用在配置结点(settings)中自定义的分析器
4,数值类型的其他属性
5,日期类型的其他属性
6,多字段(fields)
在 fields 属性中定义一个或多个字段,该字段的值和当前字段值相同,可以设置一个字段用于搜索,一个字段用于排序等。
- "properties": {
- "id": {
- "type": "long",
- "fields": {
- "id2": {
- "type": "long",
- "index": "not_analyzed"
- }
- }
- },
7,信息格式(postings_format)
postings_format 属性用于为字段指定信息格式:
8,文档值格式(doc_values_format)
文档值格式(doc_values_format),该属性定义字段的值被写入到具有较高内存效率的列式结构,以便进行高效的排序和聚合搜索。使用文档值的字段将有专属的字段数据缓存实例,无需像普通字段一样倒排。
文档值格式的有效值:
配置字段的文档值格式:
- "properties": {
- "id": {
- "type": "int",
- "doc_values_format": "memory"
- },
四,附加字段
1,文档类型字段
_type 字段:用于表示文档类型,默认情况下,文档的类型会编入索引,但不会被分析,也不会被存储
- {
- "articles": {
- "_type": {
- "store": "yes"
- },
2,文档标识字段
配置文档的标识值:
- {
- "articles": {
- "_id": {
- "index": "not_analyzed",
- "store": "no",
- "path": "article_id"
- }
- }
- }
3,_all 字段
ElasticSearch 使用_all 字段存储其他字段的数据以便搜索,默认情况下,_all 字段是启用的,包含了索引中所有字段的数据,然而这一字段使索引变大,如果不需要,请禁用该字段,或排除某些字段。为了在_all 字段中不包括某个特定字段,在字段中设置 "include_in_all" 属性为 false。
禁用_all 字段,需要修改映射配置:
- {
- "articles": {
- "_all": {
- "enable": "false"
- }
- }
- }
4,_source 字段
_source 字段表示在生成索引的过程中,存储发送到 ElasticSearch 的原始 JSON 文档,默认情况下,该字段会被启用,因为索引的局部更新功能依赖该字段。
- {
- "articles":{
- "_source":{
- "enable":"false"
- }
- }
- }
- {
- "articles":{
- "_source":{
- "excludes":["Content","Comments"]
- }
- }
- }
5,_index 字段
_index 字段用于存储索引的信息,通过该字段,能够返回文档存储在那个索引中,默认情况下,该字段是禁用的。
- {
- "articles":{
- "_index":{
- "enable":"true"
- }
- }
- }
6,_routing 字段
在路由字段(_routing)中设置一个字段值,使用该值作为路由值。
- {
- "articles":{
- "_routing":{
- "required":"true",
- "path":"ariticle_id"
- }
- }
- }
五,索引配置节(settings)
1,配置索引的分片和副本数量
ElasticSearch 索引是有一个或多个分片组成的,每个分片是索引的一个水平分区,包含了文档数据的一部分;每个分片有 0,1 或多个副本,分片的副本和分片存储相同的数据。
示例代码,为索引创建 5 个分片,分片没有副本:
- "settings": {
- "number_of_shards": 5,
- "number_of_replicas": 0,
2,配置分析器(analyzer)
在配置结点的 analysis 属性中配置分析器,参考了解更多,
分词器(tokenizer)是系统预定义的,常用的分词器是:
过滤器是系统预定义的,常用的过滤器是:
在配置结点中,自定义分析器(analyzer)示例代码:
View Code
- {
- "settings":{
- "index":{
- "analysis":{
- "analyzer":{
- "myanalyzer_name":{
- "tokenizer":"standard",
- "filter":[
- "asciifolding",
- "lowercase",
- "ourEnglishFilter"
- ]
- }
- },
- "filter":{
- "ourEnglishFilter":{
- "type":"kstem"
- }
- }
- }
- }
- }
- }
六,删除索引
删除索引的语法是: DELETE http://localhost:9200/blog
七,更新索引
索引的更新分为逐个文档的更新和批量文档更新:
1,单个文档(Individual Document)的更新
单个文档更新的语法是:POST http://localhost:9200/blog/articles/1 + 文档对象的 JSON 数据
POST http://localhost:9200/blog/articles/1
文档对象的 JSON 数据示例如下:
- {
- "id":1,
- "title":"Elasticsearch index",
- "Author":"悦光阴",
- "content":"xxxxxxxxxxx",
- "postedat":"2017-03-14"
- }
2,批量文档的更新(Bluk)
批量文档更新的语法是:POST http://localhost:9200/_bulk + 批量文档对象的 JSON 数据,在_bulk 端进行批量更新操作。
在传递的请求主体中,每一个请求分为两个 JSON 数据,第一个 JSON 数据包含操作说明的描述信息,第二个 JSON 数据包含文档对象:
View Code
- {
- "index":{
- "_index":"blog",
- "_type":"ariticles",
- "_id":1
- }
- }
- {
- "id":1,
- "title":"Elasticsearch index",
- "Author":"悦光阴",
- "content":"xxxxxxxxxxx",
- "postedat":"2017-03-14"
- }
- {
- "index":{
- "_index":"blog",
- "_type":"ariticles",
- "_id":2
- }
- }
- {
- "id":2,
- "title":"Elasticsearch index",
- "Author":"悦光阴",
- "content":"xxxxxxxxxxx",
- "postedat":"2017-03-14"
- }
八,搜索索引
在_search 端对文档数据进行搜索,索引搜索的语法非常复杂,ElasticSearch 支持聚合查询和简单查询
1,按照路由搜索
路由可以控制文档和查询转发的目的分片,ElasticSearch 计算路由字段的哈希值,对于相同的路由值,将产生相同的哈希值,分配到特定的分片上;如果在查询时,指定路由值,那么只需要搜索单个分片而不是整个索引,就能获取查询结果。
路由字段由文档类型的_routing 属性定义,在查询时,使用 routing 参数来查找特定路由的文档:
GET http://localhost:9200/blog/_search?routing=1235&q=article_id=100
2,聚合和简单查询
下回分解
附:索引的配置文档
View Code
- {
- "settings":{
- "number_of_shards":1,
- "number_of_replicas":0,
- "index":{
- "analysis":{
- "analyzer":{
- "my_analyzer_name":{
- "tokenizer":"standard",
- "filter":[
- "asciifolding",
- "lowercase",
- "ourEnglishFilter"
- ]
- }
- },
- "filter":{
- "ourEnglishFilter":{
- "type":"kstem"
- }
- }
- }
- }
- },
- "mappings":{
- "doc_type_name":{
- "_routing":{
- "required":"true",
- "path":"doc_field1"
- },
- "_analyzer":{
- "path":"doc_field2"
- },
- "_id":{
- "path":"doc_field3"
- },
- "_type":{
- "store":"yes"
- },
- "_all":{
- "enable":"false"
- },
- "_source":{
- "enable":"false"
- },
- "_idex":{
- "enable":"true"
- },
- "number_detection":"true",
- "dynamic_date_formats":[
- "yyyy-MM-dd"
- ],
- "dynamic":"false",
- "properties":{
- "doc_string_fields":{
- "type":"string",
- "store":"yes",
- "index":"analyzed",
- "fields":{
- "doc_string_field_other_name":{
- "type":"string",
- "index":"no_analyzed"
- }
- }
- }
- }
- }
- }
- }
参考文档:
来源: http://www.cnblogs.com/ljhdo/p/4981928.html