//数据库和es的对应关系
//如下接口调用都是使用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
}
}
]
}
}