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)的,当我们执行以下命令:
ES能非常聪明的识别出"name"和"description"字段的类型是string, ES默认会创建以下的mapping。
什么是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字段的转换过程:
可以看到, 我们的description字段的值转换成了[pretty], [cool], [guy], 在转换过程中大写的A, 标点符号都被filter过滤掉了, Pretty也转成了全小写的pretty, 这里比较重要的是, 即使ES存储数据的时候仍然存储的是完整的数据, 但是可以搜索到这条数据的关键字只剩下这三个单词了, 其他的都是抛弃掉了。
看看以单词a来搜索的结果:
text类型的搜索在查询过程中使用了和之前插入数据相同的分析/过滤系统, 所以我们输入"a",mapping不会有任何返回, 因为单词“a”不会被ES存储和索引。反过来,如果我们使用单词"cool"进行搜索:
上面说到的是 默认 mapping,那么我们怎么建立 自己的 mapping 呢?
比如 botnet.json(botnet 的 mapping 文件)
文件 放在 config/templates/ 下
目录 位于 D:\soft\work\DB\elasticsearch-1.7.0\elasticsearch-1.7.0\config\templates\botnet.json
说明:1.建立 mapping 的 规则是 将要 聚合的field 不可分词 ,设置成
2.预留出 空余字段 ,因为 索引的结构一旦 设置成 存上数据,就不可改变 (不像mysql 等),所以 在 设计的时候 就应该 预留出 扩展字段 String long 型的 都要 流出余地来。
mapping相当于 在关系型 的ddl 建表语言 :
不足之处 请指正!
几个基本名词
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 学习博客系列<三> ES 中 index-doc 的 添加(java)
- elasticsearch 学习博客系列<四> ES 中 index-doc 的 删除(java)
- elasticsearch 学习博客系列<五> ES 中 index-doc 的 更新(java)
- elasticsearch 学习博客系列<一> ES 的安装与配置
- CocosCreator项目学习系列<二>关于Button(添加事件)输入控制交互条件的触发_实现虚拟按钮控制_JavaScript
- 学习数学系列<二>
- Mule 学习系列<二> File Transport
- 菜鸟的Hadoop学习之路系列<二>:Hadoop集群构成和HDFS
- Android NDK学习 <六> 复杂结构动态库处理和第三方库的移植
- (三十二):设置属性:<jsp:setProperty> (JSP学习第九天)
- QUnit系列 -- 5.QUnit源码分析之<大致结构>
- LDD3学习-第十章-中断处理<二>
- JAVA高新技术学习<二>
- (转)MFC技巧学习<二>
- Android NDK学习 <六> 复杂结构动态库处理和第三方库的移植
- ExtX系列文件系统的结构学习_sigaction-ChinaUnix博客
- SQL 学习笔记<二> INSERT, UPDATE, DELETE, SELECT
- PostgreSQL学习手册(函数和操作符<二>)
- 学习笔记<二>动态图层的制作,地图Behaviors和Actions的添加
- JAVA基础学习--IO流总结<二>