ES kibana常用语法---增删改查_es 空字符串值查询

}


### 分页查询



GET test/doc/_search
{
“query”: {
“match_phrase_prefix”: {
“name”: “wang”
}
},
“from”: 0,
“size”: 1
}


### bool 查询 (must、should)


**bool 查询总结**  
 must:与关系,相当于关系型数据库中的 and。  
 should:或关系,相当于关系型数据库中的 or。  
 must\_not:非关系,相当于关系型数据库中的 not。  
 filter:过滤条件。  
 range:条件筛选范围。  
 gt:大于,相当于关系型数据库中的 >。  
 gte:大于等于,相当于关系型数据库中的 >=。  
 lt:小于,相当于关系型数据库中的 <。  
 lte:小于等于,相当于关系型数据库中的 <=。


#### must


(must字段对应的是个列表,也就是说可以有多个并列的查询条件,一个文档满足各个子条件后才最终返回)


##### 单条件查询



GET test/doc/_search
{
“query”: {
“bool”: {
“must”: [
{
“match”: {
“name”: “wangfei”
}
}
]
}
}
}


##### 多条件组合查询



GET test/doc/_search
{
“query”: {
“bool”: {
“must”: [
{
“match”: {
“name”: “wanggfei”
}
},
{
“match”: {
“age”: 25
}
}
]
}
}
}


#### should


(只要符合其中一个条件就返回)



GET test/doc/_search
{
“query”: {
“bool”: {
“should”: [
{
“match”: {
“name”: “wangjifei”
}
},
{
“match”: {
“age”: 27
}
}
]
}
}
}


#### must\_not



GET test/doc/_search
{
“query”: {
“bool”: {
“must_not”: [
{
“match”: {
“name”: “wangjifei”
}
},
{
“match”: {
“age”: 27
}
}
]
}
}
}


#### filter


(条件过滤查询,过滤条件的范围用range表示gt表示大于、lt表示小于、gte表示大于等于、lte表示小于等于)



GET test/doc/_search
{
“query”: {
“bool”: {
“must”: [
{
“match”: {
“name”: “wangjifei”
}
}
],
“filter”: {
“range”: {
“age”: {
“gte”: 10,
“lt”: 27
}
}
}
}
}
}


#### 查询结果过滤



GET test3/doc/_search
{
“query”: {
“match”: {
“name”: “顾”
}
},
“_source”: [“name”,“age”]
}

查询结果
{
“took” : 58,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test3”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“name” : “顾老二”,
“age” : 30
}
}
]
}
}


#### 查询结果高亮显示 (默认高亮显示)



GET test3/doc/_search
{
“query”: {
“match”: {
“name”: “顾老二”
}
},
“highlight”: {
“fields”: {
“name”: {}
}
}
}

查询结果
{
“took” : 216,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 0.8630463,
“hits” : [
{
“_index” : “test3”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.8630463,
“_source” : {
“name” : “顾老二”,
“age” : 30,
“from” : “gu”,
“desc” : “皮肤黑、武器长、性格直”,
“tags” : [
“黑”,
“长”,
“直”
]
},
“highlight” : {
“name” : [

]
}
}
]
}
}


### 精确查询与模糊查询


**term 和 match 的区别是:**  
 match 经过分词,用于模糊查询,可以查看某个字段值中的部分词  
 term 不经过分词,只能匹配到完整的字段值,用于精确查询



准备数据

PUT w1
{
“mappings”: {
“doc”: {
“properties”:{
“t1”:{
“type”: “text”
},
“t2”: {
“type”: “keyword”
}
}
}
}
}

PUT w1/doc/1
{
“t1”: “hi single dog”,
“t2”: “hi single dog”
}

t1类型为text,会经过分词,match查询时条件也会经过分词,所以下面两种查询都能查到结果

GET w1/doc/_search
{
“query”: {
“match”: {
“t1”: “hi single dog”
}
}
}

GET w1/doc/_search
{
“query”: {
“match”: {
“t1”: “hi”
}
}
}

t2类型为keyword类型,不会经过分词,match查询时条件会经过分词,所以只能当值为"hi single dog"时能查询到

GET w1/doc/_search
{
“query”: {
“match”: {
“t2”: “hi”
}
}
}

GET w1/doc/_search
{
“query”: {
“match”: {
“t2”: “hi single dog”
}
}
}

t1类型为text,会经过分词,term查询时条件不会经过分词,所以只有当值为"hi"时能查询到

GET w1/doc/_search
{
“query”: {
“term”: {
“t1”: “hi single dog”
}
}
}

GET w1/doc/_search
{
“query”: {
“term”: {
“t1”: “hi”
}
}
}

t2类型为keyword类型,不会经过分词,term查询时条件不会经过分词,所以只能当值为"hi single dog"时能查询到

GET w1/doc/_search
{
“query”: {
“term”: {
“t2”: “hi single dog”
}
}
}

GET w1/doc/_search
{
“query”: {
“term”: {
“t2”: “hi”
}
}
}

  • 查找多个精确值(terms)
第一个查询方式

GET test/doc/_search
{
“query”: {
“bool”: {
“should”: [
{
“term”: {
“age”:27
}
},{
“term”:{
“age”:28
}
}
]
}
}
}

第二个查询方式

GET test/doc/_search
{
“query”: {
“terms”: {
“age”: [
“27”,
“28”
]
}
}
}


### 聚合查询 avg、max、min、sum



数据准备

PUT zhifou/doc/1
{
“name”:“顾老二”,
“age”:30,
“from”: “gu”,
“desc”: “皮肤黑、武器长、性格直”,
“tags”: [“黑”, “长”, “直”]
}

PUT zhifou/doc/2
{
“name”:“大娘子”,
“age”:18,
“from”:“sheng”,
“desc”:“肤白貌美,娇憨可爱”,
“tags”:[“白”, “富”,“美”]
}

PUT zhifou/doc/3
{
“name”:“龙套偏房”,
“age”:22,
“from”:“gu”,
“desc”:“mmp,没怎么看,不知道怎么形容”,
“tags”:[“造数据”, “真”,“难”]
}

PUT zhifou/doc/4
{
“name”:“石头”,
“age”:29,
“from”:“gu”,
“desc”:“粗中有细,狐假虎威”,
“tags”:[“粗”, “大”,“猛”]
}

PUT zhifou/doc/5
{
“name”:“魏行首”,
“age”:25,
“from”:“广云台”,
“desc”:“仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!”,
“tags”:[“闭月”,“羞花”]
}

GET zhifou/doc/_search
{
“query”: {
“match_all”: {}
}
}

  • 需求1、查询from是gu的人的平均年龄。
    GET zhifou/doc/_search
    {
    “query”: {
    “match”: {
    “from”: “gu”
    }
    },
    “aggs”: {
    “my_avg”: {
    “avg”: {
    “field”: “age”
    }
    }
    },
    “_source”: [“name”, “age”]
    }

查询结果
{
“took” : 83,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 3,
“max_score” : 0.6931472,
“hits” : [
{
“_index” : “zhifou”,
“_type” : “doc”,
“_id” : “4”,
“_score” : 0.6931472,
“_source” : {
“name” : “石头”,
“age” : 29
}
},
{
“_index” : “zhifou”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“name” : “顾老二”,
“age” : 30
}
},
{
“_index” : “zhifou”,
“_type” : “doc”,
“_id” : “3”,
“_score” : 0.2876821,
“_source” : {
“name” : “龙套偏房”,
“age” : 22
}
}
]
},
“aggregations” : {
“my_avg” : {
“value” : 27.0
}
}
}

上例中,首先匹配查询from是gu的数据。在此基础上做查询平均值的操作,这里就用到了聚合函数,其语法被封装在aggs中,而my_avg则是为查询结果起个别名,封装了计算出的平均值。那么,要以什么属性作为条件呢?是age年龄,查年龄的什么呢?是avg,查平均年龄。
如果只想看输出的值,而不关心输出的文档的话可以通过size=0来控制

GET zhifou/doc/_search
{
“query”: {
“match”: {
“from”: “gu”
}
},
“aggs”:{
“my_avg”:{
“avg”: {
“field”: “age”
}
}
},
“size”:0,
“_source”:[“name”,“age”]
}

查询结果
{
“took” : 35,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 3,
“max_score” : 0.0,
“hits” : [ ]
},
“aggregations” : {
“my_avg” : {
“value” : 27.0
}
}
}


* 需求2、查询年龄的最大值



GET zhifou/doc/_search
{
“query”: {
“match_all”: {}
},
“aggs”: {
“my_max”: {
“max”: {
“field”: “age”
}
}
},
“size”: 0,
“_source”: [“name”,“age”,“from”]
}

查询结果
{
“took” : 10,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 5,
“max_score” : 0.0,
“hits” : [ ]
},
“aggregations” : {
“my_max” : {
“value” : 30.0
}
}
}


* 需求3、查询年龄的最小值



GET zhifou/doc/_search
{
“query”: {
“match_all”: {}
},
“aggs”: {
“my_min”: {
“min”: {
“field”: “age”
}
}
},
“size”: 0,
“_source”: [“name”,“age”,“from”]
}

查询结果
{
“took” : 2,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 5,
“max_score” : 0.0,
“hits” : [ ]
},
“aggregations” : {
“my_min” : {
“value” : 18.0
}
}
}


* 需求4、查询符合条件的年龄之和



GET zhifou/doc/_search
{
“query”: {
“match”: {
“from”: “gu”
}
},
“aggs”: {
“my_sum”: {
“sum”: {
“field”: “age”
}
}
},
“size”: 0,
“_source”: [“name”,“age”,“from”]
}

查询结果
{
“took” : 4,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 3,
“max_score” : 0.0,
“hits” : [ ]
},
“aggregations” : {
“my_sum” : {
“value” : 81.0
}
}
}


### 分组查询


* 需求: 要查询所有人的年龄段,并且按照1520,2025,25~30分组,并且算出每组的平均年龄。



GET zhifou/doc/_search
{
“size”: 0,
“query”: {
“match_all”: {}
},
“aggs”: {
“age_group”: {
“range”: {
“field”: “age”,
“ranges”: [
{
“from”: 15,
“to”: 20
},
{
“from”: 20,
“to”: 25
},
{
“from”: 25,
“to”: 30
}
]
}
}
}
}

查询结果
{
“took” : 9,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 5,
“max_score” : 0.0,
“hits” : [ ]
},
“aggregations” : {
“age_group” : {
“buckets” : [
{
“key” : “15.0-20.0”,
“from” : 15.0,
“to” : 20.0,
“doc_count” : 1
},
{
“key” : “20.0-25.0”,
“from” : 20.0,
“to” : 25.0,
“doc_count” : 1
},
{
“key” : “25.0-30.0”,
“from” : 25.0,
“to” : 30.0,
“doc_count” : 2
}
]
}
}
}


上例中,在aggs的自定义别名age\_group中,使用range来做分组,field是以age为分组,分组使用ranges来做,from和to是范围


* 接下来,我们就要对每个小组内的数据做平均年龄处理。



GET zhifou/doc/_search
{
“size”: 0,
“query”: {
“match_all”: {}
},
“aggs”: {
“age_group”: {
“range”: {
“field”: “age”,
“ranges”: [
{
“from”: 15,
“to”: 20
},
{
“from”: 20,
“to”: 25
},
{
“from”: 25,
“to”: 30
}
]
},
“aggs”: {
“my_avg”: {
“avg”: {
“field”: “age”
}
}
}
}
}
}

查询结果
{
“took” : 1,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 5,
“max_score” : 0.0,
“hits” : [ ]
},
“aggregations” : {
“age_group” : {
“buckets” : [
{
“key” : “15.0-20.0”,
“from” : 15.0,
“to” : 20.0,
“doc_count” : 1,
“my_avg” : {
“value” : 18.0
}
},
{
“key” : “20.0-25.0”,
“from” : 20.0,
“to” : 25.0,
“doc_count” : 1,
“my_avg” : {
“value” : 22.0
}
},
{
“key” : “25.0-30.0”,
“from” : 25.0,
“to” : 30.0,
“doc_count” : 2,
“my_avg” : {
“value” : 27.0
}
}
]
}
}
}



> 
> ES的聚合查询的总结:聚合函数的使用,一定是先查出结果,然后对结果使用聚合函数做处理
> 
> 
> avg:求平均
> 
> 
> max:最大值
> 
> 
> min:最小值
> 
> 
> sum:求和
> 
> 
> 


## mapping


### mapping 是什么


映射,用于定义一个文档及其中的字段如何存储和索引


### 字段的数据类型



> 
> 简单类型如文本(text)、关键字(keyword)、日期(data)、整形(long)、双精度>、(double)、布尔(boolean)或 ip。  
>  可以是支持 JSON 的层次结构性质的类型,如对象或嵌套。  
>  或者一种特殊类型,如 geo\_point、geo\_shape 或 completion。为了不同的目的,  
>  以不同的方式索引相同的字段通常是有用的。例如,字符串字段可以作为全文搜索的文本字段进行索引,  
>  也可以作为排序或聚合的关键字字段进行索引。或者,可以使用标准分析器、英语分析器和  
>  法语分析器索引字符串字段。这就是多字段的目的。大多数数据类型通过 fields 参数支持多字段。
> 
> 
> 


### mappings 之 dynamic 的三种状态


ES 中的 mapping 用来定义索引中字段和字段属性。mapping 中的 dynamic 属性决定了新增字段的处理方式,它有三种状态:


1. true (默认值)


当 dynamic 设置为 true 时,如果文档中出现新的字段,ES 会自动将这个字段添加到 mapping 定义中,并根据字段值自动识别其类型。


2. false


当 dynamic 设置为 false 时,如果文档中出现新的字段,ES 不会自动将这个字段添加到 mapping, 而是忽略这个新增字段。


3. strict


当 dynamic 设置为 strict 时,如果文档中出现新的字段,ES 不仅不会添加这个字段到 mapping, 还会抛出异常错误。


总的来说,dynamic 属性用来控制新增字段的处理模式:


* true 会自动添加字段
* false 会忽略新增字段
* strict 会报错


通过设置不同的 dynamic 状态,可以更好地管理索引的 mapping 定义和字段。这对控制数据结构非常重要。



默认为动态映射

PUT test4
{
“mappings”: {
“doc”:{
“properties”: {
“name”: {
“type”: “text”
},
“age”: {
“type”: “long”
}
}
}
}
}

GET test4/_mapping

查询结果
{
“test4” : {
“mappings” : {
“doc” : {
“properties” : {
“age” : {
“type” : “long”
},
“name” : {
“type” : “text”
},
“sex” : {
“type” : “text”,
“fields” : {
“keyword” : {
“type” : “keyword”,
“ignore_above” : 256
}
}
}
}
}
}
}
}

#####添加数据
PUT test4/doc/1
{
“name”:“wangjifei”,
“age”:“18”,
“sex”:“不详”
}

#####查看数据
GET test4/doc/_search
{
“query”: {
“match_all”: {}
}
}

查询结果
{
“took” : 8,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 1.0,
“hits” : [
{
“_index” : “test4”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 1.0,
“_source” : {
“name” : “wangjifei”,
“age” : “18”,
“sex” : “不详”
}
}
]
}
}


* 测试静态映射:当elasticsearch察觉到有新增字段时,因为dynamic:false的关系,会忽略该字段,但是仍会存储该字段。



#####创建静态mapping
PUT test5
{
“mappings”: {
“doc”:{
“dynamic”:false,
“properties”: {
“name”: {
“type”: “text”
},
“age”: {
“type”: “long”
}
}
}
}
}

#####插入数据
PUT test5/doc/1
{
“name”:“wangjifei”,
“age”:“18”,
“sex”:“不详”
}

####条件查询
GET test5/doc/_search
{
“query”: {
“match”: {
“sex”: “不详”
}
}
}

查询结果
{
“took” : 9,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 0,
“max_score” : null,
“hits” : [ ]
}
}

#####查看所有数据
GET /test5/doc/_search
{
“query”: {
“match_all”: {}
}
}

查询结果
{
“took” : 1,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 1.0,
“hits” : [
{
“_index” : “test5”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 1.0,
“_source” : {
“name” : “wangjifei”,
“age” : “18”,
“sex” : “不详”
}
}
]
}
}


* 测试严格映射:当elasticsearch察觉到有新增字段时,因为dynamic:strict 的关系,就会报错,不能插入成功。



#####创建严格mapping
PUT test6
{
“mappings”: {
“doc”:{
“dynamic”:“strict”,
“properties”: {
“name”: {
“type”: “text”
},
“age”: {
“type”: “long”
}
}
}
}
}

#####插入数据
PUT test6/doc/1
{
“name”:“wangjifei”,
“age”:“18”,
“sex”:“不详”
}

插入结果
{
“error”: {
“root_cause”: [
{
“type”: “strict_dynamic_mapping_exception”,
“reason”: “mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed”
}
],
“type”: “strict_dynamic_mapping_exception”,
“reason”: “mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed”
},
“status”: 400
}



> 
> 小结: 动态映射(dynamic:true):动态添加新的字段(或缺省)。静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现在查询中。严格模式(dynamic:strict):如果遇到新的字段,就抛出异常。一般静态映射用的较多。就像 HTML 的 img 标签一样,src 为自带的属性,你可以在需要的时候添加 id 或者 class 属性。当然,如果你非常非常了解你的数据,并且未来很长一段时间不会改变,strict 不失为一个好选择。
> 
> 
> 


### ES 之 mappings 的 index 属性


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



PUT test7
{
“mappings”: {
“doc”: {
“properties”: {
“name”: {
“type”: “text”,
“index”: true
},
“age”: {
“type”: “long”,
“index”: false
}
}
}
}
}

####插入数据
PUT test7/doc/1
{
“name”:“wangjifei”,
“age”:18
}

####条件查询数据
GET test7/doc/_search
{
“query”: {
“match”: {
“name”: “wangjifei”
}
}
}

查询结果
{
“took” : 18,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test7”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“name” : “wangjifei”,
“age” : 18
}
}
]
}
}

#####条件查询
GET test7/doc/_search
{
“query”: {
“match”: {
“age”: 18
}
}
}

查询结果
{
“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”: “fzN9frSZRy2OzinRjeMKGA”,
“index”: “test7”
}
],
“type”: “search_phase_execution_exception”,
“reason”: “all shards failed”,
“phase”: “query”,
“grouped”: true,
“failed_shards”: [
{
“shard”: 0,
“index”: “test7”,
“node”: “INueKtviRpO1dbNWngcjJA”,
“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”: “fzN9frSZRy2OzinRjeMKGA”,
“index”: “test7”,
“caused_by”: {
“type”: “illegal_argument_exception”,
“reason”: “Cannot search on field [age] since it is not indexed.”
}
}
}
]
},
“status”: 400
}


### 5. ES 之 mappings 的copy\_to属性


ES 中的 mappings 属性中,copy\_to 属性用来将一个字段的内容拷贝到另一个字段中。


copy\_to 属性指定将源字段的内容拷贝到目标字段。当源字段的值发生变化时,目标字段也会自动更新。


使用 copy\_to 的好处是:


1. 可以将一个字段内容标准化后拷贝到另一个字段,方便后续查询。例如可以将不规范的名称字段拷贝到规范后的名称字段。
2. 可以将一个字段拆分后拷贝到多个目标字段,实现多字段查询。例如可以将姓名字段拆分后拷贝到姓和名字段。
3. 可以提高搜索效率。例如拷贝文本字段到关键词字段后,可以使用关键词字段进行快速查询过滤。


设置 copy\_to 属性需要指定源字段和目标字段。目标字段不会存储实际值,只是源字段值的拷贝。这对规范数据结构和提高查询效率很有帮助。


所以,copy\_to 属性可以让 ES 更好地管理索引结构,实现复杂的数据转换和提升查询性能。



PUT test8
{
“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 test8/doc/1
{
“first_name”:“tom”,
“last_name”:“ben”
}
PUT test8/doc/2
{
“first_name”:“john”,
“last_name”:“smith”
}

#####查询所有
GET test8/doc/_search
{
“query”: {
“match_all”: {}
}
}

查询结果
{
“took” : 4,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 2,
“max_score” : 1.0,
“hits” : [
{
“_index” : “test8”,
“_type” : “doc”,
“_id” : “2”,
“_score” : 1.0,
“_source” : {
“first_name” : “john”,
“last_name” : “smith”
}
},
{
“_index” : “test8”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 1.0,
“_source” : {
“first_name” : “tom”,
“last_name” : “ben”
}
}
]
}
}

#####条件查询
GET test8/doc/_search
{
“query”: {
“match”: {
“first_name”: “tom”
}
}
}

查询结果
{
“took” : 2,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test8”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “tom”,
“last_name” : “ben”
}
}
]
}
}

######条件查询
GET test8/doc/_search
{
“query”: {
“match”: {
“full_name”: “ben”
}
}
}

查询结果
{
“took” : 3,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test8”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “tom”,
“last_name” : “ben”
}
}
]
}
}


上例中,我们将first\_name和last\_name都复制到full\_name中。并且使用full\_name查询也返回了结果


* 既要查询tom还要查询smith该怎么办?



GET test8/doc/_search
{
“query”: {
“match”: {
“full_name”: {
“query”: “tom smith”,
“operator”: “or”
}
}
}
}

查询结果
{
“took” : 3,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 2,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test8”,
“_type” : “doc”,
“_id” : “2”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “john”,
“last_name” : “smith”
}
},
{
“_index” : “test8”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “tom”,
“last_name” : “ben”
}
}
]
}
}


operator参数为多个条件的查询关系也可以是and


* 上面的查询还可以简写成一下:



GET test8/doc/_search
{
“query”: {
“match”: {
“full_name”: “tom smith”
}
}
}


* copy\_to还支持将相同的属性值复制给不同的字段。



PUT test9
{
“mappings”: {
“doc”: {
“dynamic”:false,
“properties”: {
“first_name”:{
“type”: “text”,
“copy_to”: [“full_name1”,“full_name2”]
},
“last_name”: {
“type”: “text”,
“copy_to”: [“full_name1”,“full_name2”]
},
“full_name1”: {
“type”: “text”
},
“full_name2”:{
“type”: “text”
}
}
}
}
}

####插入数据
PUT test9/doc/1
{
“first_name”:“tom”,
“last_name”:“ben”
}

PUT test9/doc/2
{
“first_name”:“john”,
“last_name”:“smith”
}

####条件查询
GET test9/doc/_search
{
“query”: {
“match”: {
“full_name1”: “tom smith”
}
}
}

查询结果
{
“took” : 7,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 2,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test9”,
“_type” : “doc”,
“_id” : “2”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “john”,
“last_name” : “smith”
}
},
{
“_index” : “test9”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “tom”,
“last_name” : “ben”
}
}
]
}
}

#####条件查询
GET test9/doc/_search
{
“query”: {
“match”: {
“full_name2”: “tom smith”
}
}
}

查询结果
{
“took” : 7,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 2,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test9”,
“_type” : “doc”,
“_id” : “2”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “john”,
“last_name” : “smith”
}
},
{
“_index” : “test9”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“first_name” : “tom”,
“last_name” : “ben”
}
}
]
}
}


full\_name1 full\_name2两个字段都可以查出来


### 6. ES 之mappings的对象属性


ES 中的 mappings 属性允许定义对象类型的字段。对象字段可以包含多个子字段,这对于一些复杂类型的文档来说很有用。


对象字段的定义方式是:



“对象字段名”: {
“type”: “object”,
“properties”: {
“子字段1”:{
“type”: “类型”
},
“子字段2”:{
“type”: “类型”
}
}
}


对象字段的主要属性如下:


* type: 必须设置为"object", 表示这是一个对象类型。
* properties: 用于定义对象内的子字段。key 为子字段名,value 定义子字段类型。
* enabled: 默认 true, 表示是否启用该对象字段的动态添加模式。


使用对象字段可以更好地表示复杂类型的文档结构,比如用户信息包含姓名、地址等多个子字段,就可以定义为一个对象。


对象字段支持嵌套对象,可以定义多层次的复杂结构。这比单独定义每个子字段更加直观和易于管理。


对象字段也支持其他 mappings 常用属性,如 analyzer、format 等。它让 ES 能更好地处理和查询结构化文档数据。


* 首先先看看ES自动创建的mappings



PUT test10/doc/1
{
“name”:“wangjifei”,
“age”:18,
“info”:{
“addr”:“北京”,
“tel”:“18500327026”
}
}

GET test10

查询结果
{
“test10” : {
“aliases” : { },
“mappings” : {
“doc” : {
“properties” : {
“age” : {
“type” : “long”
},
“info” : {
“properties” : {
“addr” : {
“type” : “text”,
“fields” : {
“keyword” : {
“type” : “keyword”,
“ignore_above” : 256
}
}
},
“tel” : {
“type” : “text”,
“fields” : {
“keyword” : {
“type” : “keyword”,
“ignore_above” : 256
}
}
}
}
},
“name” : {
“type” : “text”,
“fields” : {
“keyword” : {
“type” : “keyword”,
“ignore_above” : 256
}
}
}
}
}
},
“settings” : {
“index” : {
“creation_date” : “1570975011394”,
“number_of_shards” : “5”,
“number_of_replicas” : “1”,
“uuid” : “YvMGDHxkSri0Lgx6GGXiNw”,
“version” : {
“created” : “6080299”
},
“provided_name” : “test10”
}
}
}
}


* 现在如果要以info中的tel为条件怎么写查询语句呢?



GET test10/doc/_search
{
“query”: {
“match”: {
“info.tel”: “18500327026”
}
}
}

查询结果
{
“took” : 5,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 0.2876821,
“hits” : [
{
“_index” : “test10”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 0.2876821,
“_source” : {
“name” : “wangjifei”,
“age” : 18,
“info” : {
“addr” : “北京”,
“tel” : “18500327026”
}
}
}
]
}
}


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


### 7. ES之mappings的settings 设置


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



PUT test11
{
“mappings”: {
“doc”: {
“properties”: {
“name”: {
“type”: “text”
}
}
}
},
“settings”: {
“number_of_replicas”: 1,
“number_of_shards”: 5
}
}


number\_of\_shards是主分片数量(每个索引默认5个主分片),而number\_of\_replicas是复制分片,默认一个主分片搭配一个复制分片。


### 8. ES 之mappings的ignore\_above参数


* ignore\_above参数仅针对于keyword类型有用



这样设置是会报错的

PUT test12
{
“mappings”: {
“doc”: {
“properties”: {
“name”: {
“type”: “text”,
“ignore_above”:5
}
}
}
}
}

显示结果
{
“error”: {
“root_cause”: [
{
“type”: “mapper_parsing_exception”,
“reason”: “Mapping definition for [name] has unsupported parameters: [ignore_above : 5]”
}
],
“type”: “mapper_parsing_exception”,
“reason”: “Failed to parse mapping [doc]: Mapping definition for [name] has unsupported parameters: [ignore_above : 5]”,
“caused_by”: {
“type”: “mapper_parsing_exception”,
“reason”: “Mapping definition for [name] has unsupported parameters: [ignore_above : 5]”
}
},
“status”: 400
}



正确的打开方式

PUT test12
{
“mappings”: {
“doc”: {
“properties”: {
“name”: {
“type”: “keyword”,
“ignore_above”:5
}
}
}
}
}

PUT test12/doc/1
{
“name”:“wangjifei”
}

这样查询能查出结果

GET test12/doc/_search
{
“query”: {
“match_all”: {}
}
}

查询结果
{
“took” : 1,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 1,
“max_score” : 1.0,
“hits” : [
{
“_index” : “test12”,
“_type” : “doc”,
“_id” : “1”,
“_score” : 1.0,
“_source” : {
“name” : “wangjifei”
}
}
]
}
}

######这样查询不能查询出结果
GET test12/doc/_search
{
“query”: {
“match”: {
“name”: “wangjifei”
}
}
}

查询结果
{
“took” : 1,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : 0,
“max_score” : null,
“hits” : [ ]
}
}


上面的例子证明超过ignore\_above设定的值后会被存储但不会建立索引


* 那么如果字符串的类型是text时能用ignore\_above吗,答案是能,但要特殊设置:



PUT test13
{
“mappings”: {
“doc”:{
“properties”:{
“name1”:{
“type”:“keyword”,
“ignore_above”:5
},
“name2”:{
“type”:“text”,
“fields”:{
“keyword”:{
“type”:“keyword”,
“ignore_above”: 10
}
}
}
}
}
}
}

PUT test13/doc/1
{
“name1”:“wangfei”,
“name2”:“wangjifei hello”
}

能查出来

GET test13/doc/_search
{
“query”: {
“match_all”: {}
}
}

查询结果
{
“took” : 4,
“timed_out” : false,
“_shards” : {
“total” : 5,
“successful” : 5,
“skipped” : 0,
“failed” : 0
},

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值