Justin-刘清政的博客

db/Elasticsearch系列/9-11文档操作/11-Elasticsearch之mappings的其他设置:index、copy_to、对象属性、settings

2020-03-10

一 前言

上一小节中,根据dynamic的状态不同,我们对字段有了更多可自定义的操作。现在再来补充一个参数,使自定义的属性更加的灵活。

二 index

首先来创建一个mappings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PUT m4
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"name": {
"type": "text",
"index": true
},
"age": {
"type": "long",
"index": false
}
}
}
}
}

可以看到,我们在创建索引的时候,为每个属性添加一个index参数。那会有什么效果呢?
先来添加一篇文档:

1
2
3
4
5
PUT m4/doc/1
{
"name": "小黑",
"age": 18
}

再来查询看效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GET m4/doc/_search
{
"query": {
"match": {
"name": "小黑"
}
}
}

GET m4/doc/_search
{
"query": {
"match": {
"age": 18
}
}
}

name查询没问题,但是,以age作为查询条件就有问题了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
"error": {
"root_cause": [
{
"type": "query_shard_exception",
"reason": "failed to create query: {\n \"match\" : {\n \"age\" : {\n \"query\" : 18,\n \"operator\" : \"OR\",\n \"prefix_length\" : 0,\n \"max_expansions\" : 50,\n \"fuzzy_transpositions\" : true,\n \"lenient\" : false,\n \"zero_terms_query\" : \"NONE\",\n \"auto_generate_synonyms_phrase_query\" : true,\n \"boost\" : 1.0\n }\n }\n}",
"index_uuid": "GHBPeT5pRnSi3g6DkpIkow",
"index": "m4"
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "m4",
"node": "dhkqLLTsRemm7qEgRdpvTg",
"reason": {
"type": "query_shard_exception",
"reason": "failed to create query: {\n \"match\" : {\n \"age\" : {\n \"query\" : 18,\n \"operator\" : \"OR\",\n \"prefix_length\" : 0,\n \"max_expansions\" : 50,\n \"fuzzy_transpositions\" : true,\n \"lenient\" : false,\n \"zero_terms_query\" : \"NONE\",\n \"auto_generate_synonyms_phrase_query\" : true,\n \"boost\" : 1.0\n }\n }\n}",
"index_uuid": "GHBPeT5pRnSi3g6DkpIkow",
"index": "m4",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Cannot search on field [age] since it is not indexed."
}
}
}
]
},
"status": 400
}

返回的是报错结果,这其中就是index参数在起作用。

小结:index属性默认为true,如果该属性设置为false,那么,elasticsearch不会为该属性创建索引,也就是说无法当做主查询条件。

三 copy_to

现在,再来学习一个copy_to属性,该属性允许我们将多个字段的值复制到组字段中,然后将组字段作为单个字段进行查询。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
PUT m5
{
"mappings": {
"doc": {
"dynamic":false,
"properties": {
"first_name":{
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text"
}
}
}
}
}

PUT m5/doc/1
{
"first_name":"tom",
"last_name":"ben"
}
PUT m5/doc/2
{
"first_name":"john",
"last_name":"smith"
}

GET m5/doc/_search
{
"query": {
"match": {
"first_name": "tom"
}
}
}

GET m5/doc/_search
{
"query": {
"match": {
"full_name": "tom"
}
}
}

上例中,我们将first_namelast_name都复制到full_name中。并且使用full_name查询也返回了结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "m5",
"_type" : "doc",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"first_name" : "tom",
"last_name" : "ben"
}
}
]
}
}

返回结果表示查询成功。那么想要查询tom或者smith该怎么办?

1
2
3
4
5
6
7
8
9
10
11
GET m5/doc/_search
{
"query": {
"match": {
"full_name": {
"query": "tom smith",
"operator": "or"
}
}
}
}

将查询条件以空格隔开并封装在query内,operator参数为多个条件的查询关系也可以是and,也有简写方式:

1
2
3
4
5
6
7
8
GET m5/doc/_search
{
"query": {
"match": {
"full_name": "tom smith"
}
}
}

copy_to还支持将相同的属性值复制给不同的字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
PUT m6
{
"mappings": {
"doc": {
"dynamic":false,
"properties": {
"first_name":{
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": ["field1", "field2"]
},
"field1": {
"type": "text"
},
"field2": {
"type": "text"
}
}
}
}
}


PUT m6/doc/1
{
"first_name":"tom",
"last_name":"ben"
}
PUT m6/doc/2
{
"first_name":"john",
"last_name":"smith"
}

上例中,只需要将copy_to的字段以数组的形式封装即可。无论是通过field1还是field2都可以查询。
小结:

  • copy_to复制的是属性值而不是属性
  • copy_to如果要应用于聚合请将filddata设置为true
  • 如果要将属性值复制给多个字段,请用数组,比如copy_to:["field1", "field2"]

四 对象属性

现在,有一个个人信息文档如下:

1
2
3
4
5
6
7
8
9
PUT m7/doc/1
{
"name":"tom",
"age":18,
"info":{
"addr":"北京",
"tel":"10010"
}
}

首先,这样嵌套多层的mappings该如何设计呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
PUT m7
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "text"
},
"info": {
"properties": {
"addr": {
"type": "text"
},
"tel": {
"type" : "text"
}
}
}
}
}
}
}

那么,如果要以name或者age属性作为查询条件查询难不倒我们。
现在如果要以info中的tel为条件怎么写查询语句呢?

1
2
3
4
5
6
7
8
GET mapping_test9/doc/_search
{
"query": {
"match": {
"info.tel": "10086"
}
}
}

上例中,info既是一个属性,也是一个对象,我们称为info这类字段为对象型字段。该对象内又包含addrtel两个字段,如上例这种以嵌套内的字段为查询条件的话,查询语句可以以字段点子字段的方式来写即可。

五 settings设置

5.1 设置主、复制分片

在创建一个索引的时候,我们可以在settings中指定分片信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PUT s1
{
"mappings": {
"doc": {
"properties": {
"name": {
"type": "text"
}
}
}
},
"settings": {
"number_of_replicas": 1,
"number_of_shards": 5
}
}

number_of_shards是主分片数量(每个索引默认5个主分片),而number_of_replicas是复制分片,默认一个主分片搭配一个复制分片。

使用支付宝打赏
使用微信打赏

点击上方按钮,请我喝杯咖啡!

扫描二维码,分享此文章