您的位置:首页 > 移动开发

elasticsearch 学习博客系列<二> ES 中 index 设置 Mapping(表结构)

2017-06-01 22:40 806 查看
通过上一篇 我们了解到ES中的一些概念,回顾一下:


几个基本名词

index: es里的index相当于一个数据库。 
type: 相当于数据库里的一个表。 
id: 唯一,相当于主键。 
node:节点是es实例,一台机器可以运行多个实例,但是同一台机器上的实例在配置文件中要确保http和tcp端口不同。 
cluster:代表一个集群,集群中有多个节点,其中有一个会被选为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。 
shards:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上,构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。 
replicas:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当个某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
下面我们说一下  表的结构 映射 mapping

默认mapping
elasticsearch(以下简称ES)是没有模式(schema)的,当我们执行以下命令:

curl -XPUT http://localhost:9200/test/item/1 -d '{"name":"zach", "description": "A Pretty cool guy."}


ES能非常聪明的识别出"name"和"description"字段的类型是string, ES默认会创建以下的mapping。

mappings: {
item: {
properties: {
description: {
type: string
}
name: {
type: string
}
}
}
}


什么是mapping
ES的mapping非常类似于静态语言中的数据类型:声明一个变量为int类型的变量, 以后这个变量都只能存储int类型的数据。同样的, 一个number类型的mapping字段只能存储number类型的数据。
同语言的数据类型相比,mapping还有一些其他的含义,mapping不仅告诉ES一个field中是什么类型的值, 它还告诉ES如何索引数据以及数据是否能被搜索到。
当你的查询没有返回相应的数据, 你的mapping很有可能有问题。当你拿不准的时候, 直接检查你的mapping。

剖析mapping
一个mapping由一个或多个analyzer组成, 一个analyzer又由一个或多个filter组成的。当ES索引文档的时候,它把字段中的内容传递给相应的analyzer,analyzer再传递给各自的filters。
filter的功能很容易理解:一个filter就是一个转换数据的方法, 输入一个字符串,这个方法返回另一个字符串,比如一个将字符串转为小写的方法就是一个filter很好的例子。
一个analyzer由一组顺序排列的filter组成,执行分析的过程就是按顺序一个filter一个filter依次调用, ES存储和索引最后得到的结果。
总结来说, mapping的作用就是执行一系列的指令将输入的数据转成可搜索的索引项。

默认analyzer
回到我们的例子, ES猜测description字段是string类型,于是默认创建一个string类型的mapping,它使用默认的全局analyzer, 默认的analyzer是标准analyzer,
这个标准analyzer有三个filter:token filter, lowercase filter和stop token filter。
我们可以在做查询的时候键入_analyze关键字查看分析的过程。使用以下指令查看description字段的转换过程:

curl -X GET "http://localhost:9200/test/_analyze?analyzer=standard&pretty=true" -d "A Pretty cool guy."

{
"tokens" : [ {
"token" : "pretty",
"start_offset" : 2,
"end_offset" : 8,
"type" : "<ALPHANUM>",
"position" : 2
}, {
"token" : "cool",
"start_offset" : 9,
"end_offset" : 13,
"type" : "<ALPHANUM>",
"position" : 3
}, {
"token" : "guy",
"start_offset" : 14,
"end_offset" : 17,
"type" : "<ALPHANUM>",
"position" : 4
} ]


可以看到, 我们的description字段的值转换成了[pretty], [cool], [guy], 在转换过程中大写的A, 标点符号都被filter过滤掉了, Pretty也转成了全小写的pretty, 这里比较重要的是, 即使ES存储数据的时候仍然存储的是完整的数据, 但是可以搜索到这条数据的关键字只剩下这三个单词了, 其他的都是抛弃掉了。

看看以单词a来搜索的结果:

$ curl -X GET "http://localhost:9200/test/_search?pretty=true" -d '{
"query" : {
"text" : { "description": "a" }
}
}'

{
"took" : 29,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}


text类型的搜索在查询过程中使用了和之前插入数据相同的分析/过滤系统, 所以我们输入"a",mapping不会有任何返回, 因为单词“a”不会被ES存储和索引。反过来,如果我们使用单词"cool"进行搜索:

curl -X GET "http://localhost:9200/test/_search?pretty=true" -d '{
"query" : {
"text" : { "description": "cool" }
}
}'

{
"took" : 29,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.15342641,
"hits" : [ {
"_index" : "test",
"_type" : "item",
"_id" : "1",
"_score" : 0.15342641, "_source" : {"name":"zach", "description": "A pretty cool guy"}
} ]
}
}


上面说到的是 默认 mapping,那么我们怎么建立 自己的 mapping 呢?
比如 botnet.json(botnet 的 mapping 文件)

文件 放在 config/templates/ 下

目录 位于  D:\soft\work\DB\elasticsearch-1.7.0\elasticsearch-1.7.0\config\templates\botnet.json

{
"template-botnet": {
"template": "botnet*",
"settings": {
"index.number_of_shards": 12,// 分片数
"number_of_replicas": 1,// 副本数
"index": {
"store": {
"compress": {
"stored": true,
"tv": true
}
}
}
},
"mappings": {
"botnet": {
"_source": {
"compress": true
},
"_all": {
"enabled": false
},
"properties": {
"lid": {
"type": "long",
"index": "not_analyzed"// 聚合 字段 不可分词
},
"url": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"ip": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"ipLong": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"port": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"source": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"state": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"type": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"firstCreateTime": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"createTime": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"updateTime": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"bigArea": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"smallArea": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"geoX": {
"type": "double",
"fielddata": {
"format": "doc_values"
}
},
"geoY": {
"type": "double",
"fielddata": {
"format": "doc_values"
}
},
"note": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"action": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"prot": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"reliability": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"isLive": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"system": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
},
"port": {
"type": "long",
"fielddata": {
"format": "doc_values"
}
},
"countryCode": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
}
}
}
}
}
}


说明:1.建立 mapping 的 规则是   将要 聚合的field 不可分词 ,设置成 

"bigArea": {
"type": "string",
"fielddata": {
"format": "doc_values"
},
"index": "not_analyzed"
}


 2.预留出 空余字段 ,因为 索引的结构一旦 设置成 存上数据,就不可改变 (不像mysql 等),所以 在  设计的时候 就应该  预留出 扩展字段  String  long  型的 都要 流出余地来。

mapping相当于 在关系型 的ddl 建表语言   :

CREATE TABLE `workers_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`workername` varchar(20) NOT NULL,
`sex` enum(F,M,S),
`salary` int(11) DEFAULT '0',
`email`  varchar(30),
`EmployedDates`  date,
`department`  varchar(30),
PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;


不足之处 请指正!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  elasticsearch 结构