基本增删改查(CURD)
操作中注意:1.当执行PUT
命令时,如果数据不存在,则新增该条数据,如果数据存在则修改该条数据。
2.PUT
命令,在做修改操作时,如果未指定其他的属性,则按照指定的属性进行修改操作。
3.POST
命令,这里可用来执行修改操作(还有其他的功能),POST
命令配合_update
完成修改操作,指定修改的内容放到doc
中。
1 PUT user/doc/1 2 { 3 "name":"热狗", 4 "age":18, 5 "sex":"男", 6 "tags":"闷骚", 7 "b":"19970715" 8 } 9 10 PUT user/doc/2 11 { 12 "name":"爆音", 13 "age":20, 14 "sex":"男", 15 "tags":"浪", 16 "b":"19970521" 17 } 18 19 PUT user/doc/3 20 { 21 "name":"和苏", 22 "age":21, 23 "sex":"女", 24 "tags":"高冷", 25 "b":"19980621" 26 } 27 28 PUT user/doc/4 29 { 30 "name":"宝石", 31 "age":25, 32 "sex":"男", 33 "tags":"实力高手", 34 "b":"19940421" 35 } 36 37 PUT user/doc/5 38 { 39 "name":"TT", 40 "age":24, 41 "sex":"男", 42 "tags":"就是帅", 43 "b":"19981201" 44 } 45 46 GET user/doc/1 47 48 GET user/doc/_search 49 50 # 查询字符串 query string 51 GET user/doc/_search?q=age:22 52 53 54 # 在做修改时操作,如果未指定其它的字段,则按照指定的字段进行修改,未指定的字段就不复存在了 55 PUT user/doc/4 56 { 57 "tags":"帅气" 58 } 59 60 GET user/doc/4 61 62 63 # 修改指定字段使用POST 64 POST user/doc/4/_update 65 { 66 "doc":{ 67 "tags":"高手" 68 } 69 } 70 71 DELETE user/doc/5 72 73 DELETE user 74 75 POST user/doc/_delete_by_query?q=age:18
查询的两种方式
1.查询字符串 query string
2.DSL结构化查询
1 # 查询的两种方式 2 # 1.查询字符串 query string 3 GET user/doc/_search?q=age:22 4 5 # 2.DSL结构化查询 6 GET user/doc/_search 7 { 8 "query": { 9 "match": { 10 "age": "24" 11 } 12 } 13 } 14 15 16 GET user/doc/_search 17 { 18 "query": { 19 "match": { 20 "tags": "浪 就是帅" 21 } 22 } 23 } 24 25 26 # 查所有 27 GET user/doc/_search 28 GET user/doc/_search 29 { 30 "query": { 31 "match_all": {} 32 } 33 }
复杂查询(按照条件查询)
1 GET user/doc/_search 2 { 3 "query": { 4 "match": { 5 "tags": "浪 就是帅" 6 } 7 } 8 } 9 10 11 # 查所有 12 GET user/doc/_search 13 GET user/doc/_search 14 { 15 "query": { 16 "match_all": {} 17 } 18 }
排序(sort desc降序 asc升序)
1 GET user/doc/_search 2 { 3 "query": { 4 "match_all": {} 5 }, 6 "sort": [ 7 { 8 "age": { 9 "order": "asc" 10 } 11 } 12 ] 13 } 14 15 16 GET user/doc/_search 17 { 18 "query": { 19 "match_all": {} 20 }, 21 "sort": [ 22 { 23 "age": { 24 "order": "desc" 25 } 26 } 27 ] 28 }
分页(from/size)
1 # 分页 2 GET user/doc/_search 3 { 4 "query": { 5 "match_all": {} 6 }, 7 "from": 2, 8 "size": 2 9 } 10 11 GET user/doc/_search 12 { 13 "query": { 14 "match_all": {} 15 }, 16 "from": 4, 17 "size": 2 18 }
布尔查询bool: should(or) must(and) must_not(not)
1 GET user/doc/_search 2 { 3 "query": { 4 "match_all": {} 5 }, 6 "from": 2, 7 "size": 2 8 } 9 10 GET user/doc/_search 11 { 12 "query": { 13 "match_all": {} 14 }, 15 "from": 4, 16 "size": 2 17 } 18 19 20 21 22 # 布尔查询bool: should(or) must(and) must_not(not) 23 GET user/doc/_search 24 { 25 "query": { 26 "bool": { 27 "should": [ 28 { 29 "match": { 30 "name": "热狗" 31 } 32 }, 33 { 34 "match": { 35 "age": "24" 36 } 37 } 38 ] 39 } 40 } 41 } 42 43 44 45 # 查询性别是男的,年龄24:must 46 GET user/doc/_search 47 { 48 "query": { 49 "bool": { 50 "must": [ 51 { 52 "match": { 53 "sex": "男" 54 } 55 }, 56 { 57 "match": { 58 "age": "24" 59 } 60 } 61 ] 62 } 63 } 64 } 65 66 67 68 69 # 查询既不是男的,又不是18岁:must_not 70 GET user/doc/_search 71 { 72 "query": { 73 "bool": { 74 "must_not": [ 75 { 76 "match": { 77 "sex": "男" 78 } 79 }, 80 { 81 "match": { 82 "age": "18" 83 } 84 } 85 ] 86 } 87 } 88 } 89 90 91 92 93 # 查询年龄大于20岁的男的文档filter range gt 94 GET user/doc/_search 95 { 96 "query": { 97 "bool": { 98 "must": [ 99 { 100 "match": { 101 "sex": "男" 102 } 103 } 104 ], 105 "filter": { 106 "range": { 107 "age": { 108 "gt": 20 109 } 110 } 111 } 112 } 113 } 114 } 115 116 117 118 # 查询年龄大于等于25的男的文档 119 GET user/doc/_search 120 { 121 "query": { 122 "bool": { 123 "must": [ 124 { 125 "match": { 126 "sex": "男" 127 } 128 } 129 ], 130 "filter": { 131 "range": { 132 "age": { 133 "gte": 25 134 } 135 } 136 } 137 } 138 } 139 } 140 141 142 143 144 145 # 查询年龄小于20的男的文档 146 GET user/doc/_search 147 { 148 "query": { 149 "bool": { 150 "must": [ 151 { 152 "match": { 153 "sex": "男" 154 } 155 } 156 ], 157 "filter": { 158 "range": { 159 "age": { 160 "lt": 20 161 } 162 } 163 } 164 } 165 } 166 }
高亮查询(highlight,pre_tags,post_tags)
1 # 查询名字是热狗的文档 2 GET user/doc/_search 3 { 4 "query": { 5 "match": { 6 "name": "热狗" 7 } 8 }, 9 "highlight": { 10 "pre_tags": "<b style='color:red;font-size:30px;' class='regou'>", 11 "post_tags": "</b>", 12 "fields": { 13 "name": {} 14 } 15 } 16 } 17 18 19 # ************************* 20 PUT user/doc/6 21 { 22 "name":"ziqi", 23 "desc":"美的打漂" 24 } 25 26 27 28 GET user/doc/_search 29 { 30 "query": { 31 "match": { 32 "desc": "打漂" 33 } 34 }, 35 "highlight": { 36 "pre_tags": "<b style='color:red;font-size:30px;' class='ziqi'>", 37 "post_tags": "</b>", 38 "fields": { 39 "desc": {} 40 } 41 } 42 }
结果过滤(_source)
1 GET user/doc/_search 2 { 3 "query": { 4 "match": { 5 "name": "TT" 6 } 7 }, 8 "_source": ["name","age","sex"] 9 }
聚合查询(avg、max、min、sum、分组)
# sum 查询所有男性年龄的总和 GET user/doc/_search { "query": { "match": { "sex": "男" } }, "aggs": { "my_sum": { "sum": { "field": "age" } } } } # max 查询年龄最大的男生 GET user/doc/_search { "query": { "match": { "sex": "男" } }, "aggs": { "my_max": { "max": { "field": "age" } } } } # min 查询年龄最小的男生 GET user/doc/_search { "aggs": { "my_min": { "min": { "field": "age" } } } } # avg 年龄平均 GET user/doc/_search { "aggs": { "my_avg": { "avg": { "field": "age" } } } } # 分组,对男性年龄,10-20, 20-30 GET user/doc/_search { "query": { "match": { "sex": "男" } }, "aggs": { "my_group": { "range": { "field": "age", "ranges": [ { "from": 10, "to": 20 }, { "from": 20, "to": 30 } ] } } } } # 分组,对男性年龄,10-20, 20-30 对每组年龄求和 GET user/doc/_search { "query": { "match": { "sex": "男" } }, "aggs": { "group":{ "range": { "field": "age", "ranges": [ { "from": 10, "to": 20 }, { "from": 20, "to": 30 } ] }, "aggs": { "my_sum": { "sum": { "field": "age" } } } } } }
mappings创建映射关系以及dynamic参数三种模式
三种模式:
mapping的dynamic的三种状态true动态模式 flase静态模式 strict严格模式
默认是true,如果插入未定义的字段,也可以通过此字段进行查找
如果自己定义false,那么此字段不能当为主的查询条件,否则hits为空
它们二者都有相同的特点:就是在查询的时候(查所有),如果之前没有定义的映射类型字段的时候它们都会返回
strict,不能新增字段
# mappings 创建映射关系 PUT s2 { "mappings": { "doc":{ "properties":{ "name":{ "type":"text" }, "age":{ "type":"long" }, "desc":{ "type":"text" } } } } } # 往自定义映射关系中插入数据 PUT s2/doc/1 { "name":"凡哥", "age":22, "desc":"低调" } PUT s2/doc/2 { "name":"潘帅", "age":25, "desc":"自带说唱特效", "tags":"帅" } # 又可以开始查询了 GET s2/doc/_search # mapping的dynamic的三种状态true动态模式 flase静态模式 strict严格模式 # 默认是true,如果插入未定义的字段,也可以通过此字段进行查找 # 如果自己定义false,那么此字段不能当为主的查询条件,否则hits为空 # 它们二者都有相同的特点:就是在查询的时候(查所有),如果之前没有定义的映射类型字段的时候它们都会返回 # strict,不能新增字段 PUT s4 { "mappings": { "doc":{ "dynamic":true, "properties":{ "name":{ "type":"text" } } } } } GET s4/_mapping PUT s4/doc/1 { "name":"那吾克热" } PUT s4/doc/2 { "name":"l4雾都", "age":"20" } GET s4/doc/_search { "query": { "match": { "name": "那吾克热" } } } GET s4/doc/_search { "query": { "match": { "age": "20" } } } PUT s5 { "mappings": { "doc":{ "dynamic":false, "properties":{ "name":{ "type":"text" } } } } } GET s5/_mapping PUT s5/doc/1 { "name":"那吾克热" } PUT s5/doc/2 { "name":"l4雾都", "age":"20" } GET s5/doc/_search { "query": { "match": { "name": "那吾克热" } } } # 查不到hits里边为空 GET s5/doc/_search { "query": { "match": { "age": "20" } } } # 在创建mapping时必须添加类型(doc),不然报错,我已经试过了 PUT s6 { "mappings": { "doc":{ "dynamic":"strict", "properties":{ "name":{ "type":"text" } } } } } PUT s6/doc/1 { "name":"好大哥" } # 直接报错 strict模式严格遵循定的字段,整死都不能加age字段 PUT s6/doc/2 { "name":"紫棋", "age":18 } GET s6/_mapping GET s6/doc/_search { "query": { "match": { "name": "好大哥" } } } PUT s3 { "mappings": { "doc":{ "properties":{ "name":{ "type":"text", "fields":{ "keyword":{ "type":"keyword", "ignore_above":64 } } }, "age":{ "type":"long" }, "desc":{ "type":"text" } } } } } GET user/_mapping GET s2/_mapping GET s3/_mapping
mappings的参数ignore_above
长度超出将不会被索引
PUT s7 { "mappings": { "doc":{ "properties":{ "title":{ "type":"keyword", "ignore_above":10 } } } } } GET s7/_mapping PUT s7/doc/1 { "title":"外交部:美国没资格对他国谈什么守信、谈什么承诺" } PUT s7/doc/2 { "title":"成都" } GET s7/doc/_search # hits为空 GET s7/doc/_search { "query": { "match": { "title": "外交部" } } } # hits也为空 GET s7/doc/_search { "query": { "match": { "title": "外交部:美国没资格对他国谈什么守信、谈什么承诺" } } } GET s7/doc/_search { "query": { "match": { "title": "成都" } } }
1 { 2 "took" : 1, 3 "timed_out" : false, 4 "_shards" : { 5 "total" : 5, 6 "successful" : 5, 7 "skipped" : 0, 8 "failed" : 0 9 }, 10 "hits" : { 11 "total" : 2, 12 "max_score" : 1.0, 13 "hits" : [ 14 { 15 "_index" : "s7", 16 "_type" : "doc", 17 "_id" : "2", 18 "_score" : 1.0, 19 "_source" : { 20 "title" : "成都" 21 } 22 }, 23 { 24 "_index" : "s7", 25 "_type" : "doc", 26 "_id" : "1", 27 "_score" : 1.0, 28 "_source" : { 29 "title" : "外交部:美国没资格对他国谈什么守信、谈什么承诺" 30 } 31 } 32 ] 33 } 34 } 35 36 37 38 39 { 40 "took" : 1, 41 "timed_out" : false, 42 "_shards" : { 43 "total" : 5, 44 "successful" : 5, 45 "skipped" : 0, 46 "failed" : 0 47 }, 48 "hits" : { 49 "total" : 0, 50 "max_score" : null, 51 "hits" : [ ] 52 } 53 } 54 55 56 57 58 59 60 61 { 62 "took" : 1, 63 "timed_out" : false, 64 "_shards" : { 65 "total" : 5, 66 "successful" : 5, 67 "skipped" : 0, 68 "failed" : 0 69 }, 70 "hits" : { 71 "total" : 0, 72 "max_score" : null, 73 "hits" : [ ] 74 } 75 } 76 77 78 79 80 { 81 "took" : 1, 82 "timed_out" : false, 83 "_shards" : { 84 "total" : 5, 85 "successful" : 5, 86 "skipped" : 0, 87 "failed" : 0 88 }, 89 "hits" : { 90 "total" : 1, 91 "max_score" : 0.2876821, 92 "hits" : [ 93 { 94 "_index" : "s7", 95 "_type" : "doc", 96 "_id" : "2", 97 "_score" : 0.2876821, 98 "_source" : { 99 "title" : "成都" 100 } 101 } 102 ] 103 } 104 }
mappings的参数index
若设置成false,不会为该字段创索引,意味着不能当主查询条件
PUT s8 { "mappings": { "doc":{ "properties":{ "t1":{ "type":"text", "index":true }, "t2":{ "type":"text", "index":false } } } } } PUT s8/doc/1 { "t1" : "论母猪的产前保养", "t2" : "论母猪的产后护理" } GET s8/doc/_search { "query": { "match": { "t1": "母猪" } } } GET s8/doc/_search { "query": { "match": { "t2": "母猪" } } }
1 { 2 "took" : 2, 3 "timed_out" : false, 4 "_shards" : { 5 "total" : 5, 6 "successful" : 5, 7 "skipped" : 0, 8 "failed" : 0 9 }, 10 "hits" : { 11 "total" : 1, 12 "max_score" : 0.5753642, 13 "hits" : [ 14 { 15 "_index" : "s8", 16 "_type" : "doc", 17 "_id" : "1", 18 "_score" : 0.5753642, 19 "_source" : { 20 "t1" : "论母猪的产前保养", 21 "t2" : "论母猪的产后护理" 22 } 23 } 24 ] 25 } 26 } 27 28 29 30 31 # 报错 32 { 33 "error": { 34 "root_cause": [ 35 { 36 "type": "query_shard_exception", 37 "reason": "failed to create query: { "match" : { "t2" : { "query" : "母猪", "operator" : "OR", "prefix_length" : 0, "max_expansions" : 50, "fuzzy_transpositions" : true, "lenient" : false, "zero_terms_query" : "NONE", "auto_generate_synonyms_phrase_query" : true, "boost" : 1.0 } } }", 38 "index_uuid": "0RDJTT8UQKy6grrB2VJx1w", 39 "index": "s8" 40 } 41 ], 42 "type": "search_phase_execution_exception", 43 "reason": "all shards failed", 44 "phase": "query", 45 "grouped": true, 46 "failed_shards": [ 47 { 48 "shard": 0, 49 "index": "s8", 50 "node": "DyXq8gbMRUKFhmD6Rgbw3g", 51 "reason": { 52 "type": "query_shard_exception", 53 "reason": "failed to create query: { "match" : { "t2" : { "query" : "母猪", "operator" : "OR", "prefix_length" : 0, "max_expansions" : 50, "fuzzy_transpositions" : true, "lenient" : false, "zero_terms_query" : "NONE", "auto_generate_synonyms_phrase_query" : true, "boost" : 1.0 } } }", 54 "index_uuid": "0RDJTT8UQKy6grrB2VJx1w", 55 "index": "s8", 56 "caused_by": { 57 "type": "illegal_argument_exception", 58 "reason": "Cannot search on field [t2] since it is not indexed." 59 } 60 } 61 } 62 ] 63 }, 64 "status": 400 65 }
mappings的参数copy_to
可以把字段的值copy给其它的字段,这样其它的字段可以做主查询条件。
同时它也可以copy多个字段
# copy_to 把t1 t2两字段的值copy给t3,t3也可以当做主查询条件 PUT s9 { "mappings": { "doc":{ "properties":{ "t1":{ "type":"text", "copy_to":"t3" }, "t2":{ "type":"text", "copy_to":"t3" }, "t3":{ "type":"text" } } } } } # copy多个字段也行试了下居然对字段类型没要求 PUT s10 { "mappings": { "doc":{ "properties":{ "t1":{ "type":"text", "copy_to":["f1", "f2"] }, "t2":{ "type":"text", "copy_to":["f1", "f2"] }, "f1":{ "type":"text" }, "f2":{ "type":"keyword" } } } } } PUT s9/doc/1 { "t1":"TT", "t2":"ziqi" } GET s9/doc/_search { "query": { "match": { "t1": "TT" } } } GET s9/doc/_search { "query": { "match": { "t2": "ziqi" } } } GET s9/doc/_search { "query": { "match": { "t3": "ziqi" } } }
三种方式都可以被查到 { "took" : 2, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.2876821, "hits" : [ { "_index" : "s9", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "t1" : "TT", "t2" : "ziqi" } } ] } }
对象属性之嵌套
PUT w1 { "mappings": { "doc":{ "properties":{ "name":{ "type":"text" }, "age":{ "type":"long" }, "info":{ "properties":{ "addr":{ "type":"text" }, "telphone":{ "type":"long" } } } } } } } GET w1/_mapping PUT w1/doc/1 { "name":"tom", "age":18, "info":{ "addr":"成都", "telphone":15555555555 } } # 查嵌套点就完事 GET w1/doc/_search { "query": { "match": { "info.addr": "成都" } } } GET w1
1 { 2 "w1" : { 3 "aliases" : { }, 4 "mappings" : { 5 "doc" : { 6 "properties" : { 7 "age" : { 8 "type" : "long" 9 }, 10 "info" : { 11 "properties" : { 12 "addr" : { 13 "type" : "text" 14 }, 15 "telphone" : { 16 "type" : "long" 17 } 18 } 19 }, 20 "name" : { 21 "type" : "text" 22 } 23 } 24 } 25 }, 26 "settings" : { 27 "index" : { 28 "creation_date" : "1566437237640", 29 "number_of_shards" : "5", 30 "number_of_replicas" : "1", 31 "uuid" : "4sGzN3COSTq3kvkgQVDZNQ", 32 "version" : { 33 "created" : "6050499" 34 }, 35 "provided_name" : "w1" 36 } 37 } 38 } 39 }
settings参数(主分片、复制分片)
主分片一旦设置不能修改,复制分片设置可以被修改,请求到来时主复制分片都会去检索,检索到返回 若主分片挂了,复制分片数据依然存在,检索到数据依然被返回,但是复制分片自动升级为主分片,内部自动会将数据进行迁移,不会丢失数据
PUT w2 { "mappings": { "doc":{ "properties":{ "name":{ "type":"text" } } } }, "settings": { "number_of_shards": 3, "number_of_replicas": 3 } } GET w2
短语查询(match_phrase,slop match_phrase_prefix最左前缀查询
注意格式
# 短语查询 PUT t1/doc/1 { "title":"中国是世界人口最多的国家" } PUT t1/doc/2 { "title":"美国是世界上军事实力最强大的国家" } PUT t1/doc/3 { "title":"北京是中国的首都" } # 会查出三篇文档返回 分词查找的 GET t1/doc/_search { "query": { "match": { "title": "中国" } } } # 短语查询 GET t1/doc/_search { "query": { "match_phrase": { "title": "中国" } } } # 查不到 GET t1/doc/_search { "query": { "match_phrase": { "title": "中国世界" } } } # slop默认1 GET t1/doc/_search { "query": { "match_phrase": { "title": { "query": "中国人口", "slop": 4 } } } } # 最左前缀查询 PUT t2/doc/1 { "title":"beautful girl" } PUT t2/doc/2 { "title":"beautful so" } GET t2/doc/_search { "query": { "match_phrase_prefix": { "title": "bea" } } } GET t2/doc/_search { "query": { "match_phrase_prefix": { "title": "gi" } } }
多字段名查询(multi_match)
PUT t3/doc/1 { "t1":"beautful girl", "t2":"beautful so" } GET t3/doc/_search { "query": { "multi_match": { "query": "beautful", "fields": ["t1", "t2"] } } } GET t3/doc/_search { "query": { "multi_match": { "query": "beautful", "fields": ["t1", "t2"], "type": "phrase" } } } GET t3/doc/_search { "query": { "multi_match": { "query": "beautful", "fields": ["t1", "t2"], "type": "phrase_prefix" } } }
分析器(analyzer-ik)
GET _analyze { "analyzer": "standard", "text": ["中国", "北京"] } GET _analyze { "analyzer": "standard", "text":"上海自来水来自海上" } GET _analyze { "analyzer": "ik_smart", "text":"上海自来水来自海上" } GET _analyze { "analyzer": "ik_max_word", "text":" 上海自来水来自海上" }
查询结果ik_smart
{ "tokens" : [ { "token" : "上海", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 }, { "token" : "自来水", "start_offset" : 2, "end_offset" : 5, "type" : "CN_WORD", "position" : 1 }, { "token" : "来自", "start_offset" : 5, "end_offset" : 7, "type" : "CN_WORD", "position" : 2 }, { "token" : "海上", "start_offset" : 7, "end_offset" : 9, "type" : "CN_WORD", "position" : 3 } ] }
ik_max_work
{ "tokens" : [ { "token" : "上海", "start_offset" : 1, "end_offset" : 3, "type" : "CN_WORD", "position" : 0 }, { "token" : "自来水", "start_offset" : 3, "end_offset" : 6, "type" : "CN_WORD", "position" : 1 }, { "token" : "自来", "start_offset" : 3, "end_offset" : 5, "type" : "CN_WORD", "position" : 2 }, { "token" : "水", "start_offset" : 5, "end_offset" : 6, "type" : "CN_CHAR", "position" : 3 }, { "token" : "来自", "start_offset" : 6, "end_offset" : 8, "type" : "CN_WORD", "position" : 4 }, { "token" : "海上", "start_offset" : 8, "end_offset" : 10, "type" : "CN_WORD", "position" : 5 } ] }
了解分析器更多https://www.elastic.co/guide/en/elasticsearch/reference/6.5/index.html
查看索引状态
GET _cat/indices
结果看起霸气各个索引信息
注意: 为什么删除映射类型?
不同映射类型具有相同名称的字段在内部由相同的Lucene支持
当我们删除一个日期字段和同一个索引中另外一个类型的字段,可能会导致失败
还有就是导致稀疏数据并干扰Lucene有效压缩文档的能力