ElasticSearch 简单的crud查询
//数据库和es的对应关系(学习文档可以参考https://es.xiaoleilu.com/010_Intro/35_Tutorial_Aggregations.html) //如下接口调用都是使用postman工具 //新增一个用户,该用户具有主键,姓名,性别,年龄三个字段,如果按照mysql的思路,我们应该先创建一个user库,然后创建一张userInfo表,接着insert一条数据进入,如果insert的时候没有指定主键值,则主键会递增 es的思路也是这样:localhost:9200/index(数据库)/type(表)/id(代表一行记录的主键,可以不写,不写的话es会自动创建),下面用这样的思路来创建一个用户: post: localhost:9200/user/userinfo/1 参数为json: { "name" : "xiaoMing", "sex":"男", "age": 18 } 响应值: { "_index": "user", //这里对应数据库userdb "_type": "userinfo", //这里对应的是数据库表 "_id": "1", //id对应一行记录的主键,代表唯一性,es是通过这个唯一的id进行倒排序的 "_version": 1, //版本号用于作乐观锁用,修改一次,版本号会加1 "result": "created", //操作的类型为新增 "_shards": { //这里代表分片,具体意思自行查询资料 "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 } //查询一个用户(使用get请求就行了) get: localhost:9200/user/userinfo/1 响应值: { "_index": "user", "_type": "userinfo", "_id": "1", "_version": 3, "found": true, "_source": { "name": "xiaoMing", "sex": "男", "age": 18 } } //修改一个用户(使用put方法) put: localhost:9200/user/userinfo/1 参数为json: { "name" : "xiaoMing", "sex":"女", "age": 140 } 响应值: { "_index": "user", "_type": "userinfo", "_id": "1", "_version": 4, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 3, "_primary_term": 1 } //删除一个用户(使用delete方法): delete:localhost:9200/user/userinfo/1 响应值: { "_index": "user", "_type": "userinfo", "_id": "1", "_version": 5, "result": "deleted", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 4, "_primary_term": 1 } //到此基本的增删改查已经完成了,后面介绍高级点的查询用法: 先新增3条记录: post:localhost:9200/user/userinfo/1 { "name" : "小花", "sex":"女", "age": 12 } post:localhost:9200/user/userinfo/2 { "name" : "小丽", "sex":"女", "age": 11 } post:localhost:9200/user/userinfo/3 { "name" : "小军", "sex":"男", "age": 22 } //查询全部 get/post不带参数: localhost:9200/user/userinfo/_search 或者使用post请求:localhost:9200/user/userinfo/_search,参数: { "query":{ "match_all":{} } } //match用来匹配指定字段的值,match会模糊匹配,例如下面查询"小军的用户,会出现所有具有小字的用户" post: localhost:9200/user/userinfo/_search { "query":{ "match":{ "name":"小军" } } } 响应结果(模糊匹配了):score代表匹配度高低,数值越大越匹配,这里小军的匹配度是最高了 { "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 3, "max_score": 0.5753642, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "3", "_score": 0.5753642, "_source": { "name": "小军", "sex": "男", "age": 22 } }, { "_index": "user", "_type": "userinfo", "_id": "2", "_score": 0.2876821, "_source": { "name": "小丽", "sex": "女", "age": 11 } }, { "_index": "user", "_type": "userinfo", "_id": "1", "_score": 0.2876821, "_source": { "name": "小花", "sex": "女", "age": 12 } } ] } } //将参数改成 { "query":{ "match":{ "name":"花" } } } 响应(只有一个值符合了): { "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "1", "_score": 0.2876821, "_source": { "name": "小花", "sex": "女", "age": 12 } } ] } } //term用于精确匹配:很多时候我们希望的是精确匹配 post: localhost:9200/user/userinfo/_search(以下所有的查询都是使用该url) { "query":{ "term":{ "name": "小军" } } } 响应: { "took": 0, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 0, "max_score": null, "hits": [] } } //上面的结果是不是很意外,明明有小军这个用户,却查不出来,如果将条件改成只有一个军字时: { "query":{ "term":{ "name": "军" } } } 响应结果: { "took": 10, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "3", "_score": 0.2876821, "_source": { "name": "小军", "sex": "男", "age": 22 } } ] } } //问题:为何term做精确查询"小军"的时候查不到数据, //原因:elasticsearch 里默认的IK分词器是会将每一个中文都进行了分词的切割,所以你直接想查一整个词,或者一整句话是无返回结果的。 解决方法使用keyword: { "query":{ "term":{ "name.keyword": "小军" } } } 响应: { "took": 5, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "3", "_score": 0.2876821, "_source": { "name": "小军", "sex": "男", "age": 22 } } ] } } //此时已经可以精确查询了 //multi_match(query_string)在多个字段上进行参数匹配 { "query":{ "multi_match":{ "query":"小军", "fields":["name","sex"] } } } 或 { "query":{ "query_string":{ "query":"小", "fields":["name","sex"] } } } 响应: { "took": 13, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "2", "_score": 0.2876821, "_source": { "name": "小丽", "sex": "女", "age": 11 } }, { "_index": "user", "_type": "userinfo", "_id": "3", "_score": 0.2876821, "_source": { "name": "小军", "sex": "男", "age": 22 } } ] } } //range进行区间查询,要数字类型才有效果,字符串没效果 gt 大于 gte 大于等于 lt 小于 lte 小于等于 请求参数: { "query":{ "range":{ "age":{ "lte":11 } } } } 响应: { "took": 92, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "2", "_score": 1, "_source": { "name": "小丽", "sex": "女", "age": 11 } } ] } } //terms多个值匹配:(精确匹配,所以加keyword) { "query":{ "terms":{ "name.keyword":["小军","小丽"] } } } 响应: { "took": 27, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 1, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "2", "_score": 1, "_source": { "name": "小丽", "sex": "女", "age": 11 } }, { "_index": "user", "_type": "userinfo", "_id": "3", "_score": 1, "_source": { "name": "小军", "sex": "男", "age": 22 } } ] } } 组合查询bool //1.跟must组合 { "query":{ "bool":{ "must":{ "match":{ "name.keyword":"小军" //此处没有keyword的话,会匹配所有带有小字和所有带有军字的记录 } } } } } 响应: { "took": 14, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "3", "_score": 0.2876821, "_source": { "name": "小军", "sex": "男", "age": 22 } } ] } } //跟must_not搭配 { "query":{ "bool":{ "must_not":{ "match":{ "name.keyword":"小军" } } } } } 响应: { "took": 17, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "2", "_score": 1, "_source": { "name": "小丽", "sex": "女", "age": 11 } } ] } } //should 满足条件的任意语句 { "query":{ "bool":{ "should":{ "match":{ "name.keyword":"小军" } } } } } 响应: { "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "3", "_score": 0.2876821, "_source": { "name": "小军", "sex": "男", "age": 22 } } ] } } //filter 必须匹配(不评分,根据过滤条件来筛选文档) { "query":{ "bool":{ "should":{ "match":{ "name":"小" } }, "filter":{ "match":{ "age":11 } } } } } 响应: { "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "2", "_score": 0.2876821, "_source": { "name": "小丽", "sex": "女", "age": 11 } } ] } } //使用constant_score可以取代只有filter的bool查询 { "query":{ "constant_score":{ "filter":{ "match":{ "age":11 } } } } } 响应: { "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": "user", "_type": "userinfo", "_id": "2", "_score": 1, "_source": { "name": "小丽", "sex": "女", "age": 11 } } ] } }