Elasticsearch Mapping之字段类型(field datatypes)
ElasticSearch支持如下数据类型:
基本类型
string (字符串类型)
字符串类型包含text与keyword两种类型。
text
文本类型,在索引文件中,存储的不是原字符串,而是使用分词器对内容进行分词处理后得到一系列的词根,然后一一存储在index的倒排索引中。
text类型支持如下映射参数:analy-zer、boost、eager_global_ordina-ls、fielddata、fielddata_frequency-filt-er、fields、index、index_optio-ns、index_prefixes、index_phras-es、norms、position_increment_g-ap、store、search_analyzer、sea-rch_quote_analyzer、similarity、t-erm_vector。keyword
关键字类型,将原始输入内容当成一个词根存储在倒排索引中,与text字段的区别是该字段不会使用分词器进行分词。
keyword类型支持如下映射参数:d-oc_values、boost、eager_global_-ordinals、fields、ignore_above、i-ndex、index_options、norms、nu-ll_value、store、similarity、norma-lizer、split_queries_on_whitespac-e。
numeric datatypes(数字类型)
long、integer、short、byte、double、float、half_float、scaled_float。
long
取值范围: -2^63~2^63-1(与java取值范围一致)integer
取值范围:-2^31~2^31-1.(与java取值范围一致)short
取值范围:-32,768~32,767(与java取值范围一致)byte
取值范围:-128~127(与java取值范围一致)double
与java取值范围一致float
与java取值范围一致half_float
浮点数,但只是用16位scaled_float
底层基于long存储,支持一个固定的精度因子,什么意思呢?如果存储浮点数0.15,如果设置scaling_fac-tor=100,则该类型会以一个整数15进行存储,有效提高其存储性能。
数值型数据类型,支持如下映射类型:boost、doc_values、format、locale、ignore_malformed、inde-x、null_value、store。
date(日期类型)
json对象没有日期类型,故java中的日期数据会被格式化,具体形式如下:
字符串类型,例如"2015-01-01"
数字类型(long),表示从1970-01-01以来的毫秒数
int类型,表示从1970-01-01以来的秒数
日期类型支持如下映射类型参数:-boost、doc_values、format、loca-le、ignore_malformed、index、nu-ll_value、store。
boolean类型
其取值为"true"、"false"、true、false。
boolean类型支持如下映射类型参数:-boost、doc_values、index、null_valu-e、store。
binary
该类型可以用来存储二进制数据,存储之前,需要先用Base64进行编码码。该字段类型默认不存储在索引中(store=fa-sle,但该值还是会存储在_source字段中-),默认也是不能用来当搜索条件。
binary类型支持如下映射类型参数:do-c_values、store。
range datatype
数据范围类型,一个字段表示一个范围,具体包含如下类型:
integer_range
float_range
double_range
date_range
ip_range
所谓的范围类型,就是一个值自身就代表一个范围,例如:
1PUT range_index
2{
3 "mappings": {
4 "_doc": {
5 "properties": {
6 "expected_attendees": {
7 "type": "integer_range"
8 }
9 }
10 }
11 }
12}
其索引数据时:
1public static void index_mapping_integer_range() {
2 RestHighLevelClient client = EsClient.getClient();
3 try {
4 IndexRequest request = new IndexRequest("mapping_test_ranger", "_doc");
5 Map<String, Object> data = new HashMap<>();
6 Map<String, Integer> pd = new HashMap<>();
7 pd.put("gte", 10);
8 pd.put("lte", 20);
9 data.put("expected_attendees", pd);
10 request.source(data);
11 System.out.println(client.index(request, RequestOptions.DEFAULT));
12 } catch (Throwable e) {
13 e.printStackTrace();
14 } finally {
15 EsClient.close(client);
16 }
17 }
搜索方式:
1public static void search_integer_range() {
2 RestHighLevelClient client = EsClient.getClient();
3 try {
4 SearchRequest searchRequest = new SearchRequest();
5 searchRequest.indices("mapping_test_ranger");
6 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
7 sourceBuilder.query(
8 //QueryBuilders.matchAllQuery()
9 //QueryBuilders.termQuery("expected_attendees", 12) // @1
10 // QueryBuilders.rangeQuery("expected_attendees").lte(30).gte(19) // @2
11 QueryBuilders.rangeQuery("expected_attendees").lte(30).gte(21) // @3
12 );
13 searchRequest.source(sourceBuilder);
14 SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
15 System.out.println(result);
16 } catch (Throwable e) {
17 e.printStackTrace();
18 } finally {
19 EsClient.close(client);
20 }
21 }
代码@1:可以通过termQuery精确匹配。
代码@2:只有定义的范围中,任意一个值匹配查询条件,则文档匹配。
代码@3:不匹配文档。
range类型支持如下映射类型参数:co-erce、boost、index、store。
复合类型
array
数组类型,不需要使用额外的类型定义,例如定义如下字段映射:
1"properties": {
2 "status_code": {
3 "type": "keyword" // 默认情况下,“doc_values”:true
4 }
5}
定义的类型为:keyword,在索引时是直接支持数组的。
1String[] keywords = new String[] {"abc","def"};
2Map<String, Object> source = new HashMap<>();
3souce.put("status_code",keywords )。
Object datatype
数据类型,对象或json对象字符串。
Nested datatype
嵌套数据类型,用于关联查询。
Geo datatypes
地图数据类型。
geo_point
地图坐标;存储经纬度。其使用场景:
Geo Bounding Box Query
找出落在指定矩形框中的坐标点Geo Distance Query
找出与指定位置在给定距离内的点找出与指定点距离在给定最小距离和最大)距离之间的点
Geo Polygon Query
查找包含在多边形范围内的文档
与地理位置相关的查询,将在整个SearchAPI讲解完成后再详细学习。
geo_shape datatype
geo_shape数据类型方便了对任意地理形状(如矩形和多边形)进行索引和搜索。当正在索引的数据或正在执行的查询包含除了点以外的形状时应该使用它。
geo相关的类型将在后面已专题方式进行讲解与学习,暂不深入学习。
特定类型
ip datatype
IP地址类型。可以存储和索引ipv4、ipv6的IP地址。
1PUT my_index
2{
3 "mappings": {
4 "_doc": {
5 "properties": {
6 "ip_addr": {
7 "type": "ip"
8 }
9 }
10 }
11 }
12}
13
14PUT my_index/_doc/1
15{
16 "ip_addr": "192.168.1.1"
17}
18GET my_index/_search
19{
20 "query": {
21 "term": {
22 "ip_addr": "192.168.0.0/16"
23 }
24 }
25}
ip datatype支持如下映射参数:boost、doc_values、index、null_value、stor-e。
Completion datatype
类型值:completion ;为了优化在查找时输入自动补全而设计的类型,输入自动补全会在查询部分专题详解。
Token count datatype
类型值:token_count,再接收一个字符串经过分析后将返回词根的个数,举例说明如下:
1PUT my_index
2{
3 "mappings": {
4 "_doc": {
5 "properties": {
6 "name": {
7 "type": "text",
8 "fields": {
9 "length": { // 为name定义的另外一个映射方式,其原始输入值还是name字段。
10 "type": "token_count", // @1
11 "analyzer": "standard" // @2
12 }
13 }
14 }
15 }
16 }
17 }
18}
@1:定义name.length字段,其类型为token_count,使用标准分词器对原始字段name的值进行分析,返回返回分析后的词根个数。
@2:分词器。
查询示例:
1PUT my_index/_doc/1
2{ "name": "John Smith" }
3
4PUT my_index/_doc/2
5{ "name": "Rachel Alice Williams" }
6
7GET my_index/_search
8{
9 "query": {
10 "term": {
11 "name.length": 3
12 }
13 }
14}
该查询条件能匹配_doc/2,因为name字段的值经过标准分词器分词后,能得到3个词根,与"name.length":3匹配。
token_count支持如下映射类型:analy-zer、enable_position_increments、bo-ost、doc_values、index、null_value、-store。
mapper-murmur3
字段类型值:murmur3。需要安装 map-per-murmur3插件,提供了在索引时索引和记录该字段的散列值,对于聚合有性能提升。
插件安装:
1sudo bin/elasticsearch-plugin install mapper-murmur3
插件卸载:
1sudo bin/elasticsearch-plugin remove mapper-murmur3
安装好插件后,需要将集群中所有的节点重新启动才能生效。
mapper-annotated-text
类型值:annotated-text,本文暂不深入学习。
Percolator type
类型值:percolator ,本文暂不深入学习。
join datatype
类型值:join。join类型允许在同一个索引中(同一个类型type)中定义多个不同类型的文档(例如学生文档、班级文档-)这些类型是个一对多关联关系(父子级联关系)。
下面根据示例来学习join type,下面先创建一个join的映射。
1PUT my_index
2{
3 "mappings": {
4 "_doc": {
5 "properties": {
6 "my_join_field": { // @1
7 "type": "join",
8 "relations": { // @2
9 "question": "answer"
10 }
11 }
12 }
13 }
14 }
15}
代码@1:定义join字段名称。
代码@2:通过relations字段来定义父子关系,其定义方式为 “父实例名称” : "子实例名称",question是answer的父类型。
索引父文档的方式如下:
1PUT my_index/_doc/1?refresh
2{
3 "text": "This is a question",
4 "my_join_field": {
5 "name": "question"
6 }
7}
8PUT my_index/_doc/2?refresh
9{
10 "text": "This is a another question",
11 "my_join_field": {
12 "name": "question"
13 }
14}
索引父文档时,在souce字段中必须指定其关系,例如"name": "question",上述索引,用JAVA实现如下:
1public static void createMapping_join_demo() { // 创建映射
2 RestHighLevelClient client = EsClient.getClient();
3 try {
4 CreateIndexRequest request = new CreateIndexRequest("map_test_join");
5 Map relations = new HashMap<>();
6 relations.put("question", "answer");
7 XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
8 .startObject()
9 .startObject("properties")
10 .startObject("text")
11 .field("type", "text")
12 .endObject()
13 .startObject("my_join_field")
14 .field("type", "join")
15 .field("relations", relations)
16 .endObject()
17 .endObject()
18 .endObject();
19 request.mapping("_doc", jsonBuilder);
20 System.out.println(client.indices().create(request, RequestOptions.DEFAULT));
21 } catch (Throwable e) {
22 e.printStackTrace();
23 } finally {
24 EsClient.close(client);
25 }
26 }
27 // 下面是构建souce字段,必须包含my_join_field,指明是父文档还是子文档。
28Map<String, Object> data1 = new HashMap();
29 data1.put("text","This is a another question");
30 Map my_join_field = new HashMap<>();
31 my_join_field.put("name", "question");
32 data1.put("my_join_field",my_join_field);
33
34//索引子文档时,必须通过parent指定父文档ID,并且其routing字段需要设置为父文档ID,确保父子文档在同一个分片上。
35PUT my_index/_doc/3?routing=1&refresh
36{
37 "text": "This is an answer",
38 "my_join_field": {
39 "name": "answer",
40 "parent": "1"
41 }
42}
关于join字段的查询,将在DSL Join ty-pe相关查询时重点介绍。
Alias datatype
类型值为:alias,可以字段指定别名,其映射定义方式如下:
1PUT trips
2{
3 "mappings": {
4 "_doc": {
5 "properties": {
6 "distance": {
7 "type": "long"
8 },
9 "route_length_miles": {
10 "type": "alias",
11 "path": "distance" // @1
12 },
13 "transit_mode": {
14 "type": "keyword"
15 }
16 }
17 }
18 }
19}
通过使用path来指定是哪个字段的别名。
Elasticsearch中支持的字段类型就介绍到这里了,下一节将介绍自动映射创建机制。
更多文章,请关注微信公众号: