ElasticSearch 基本使用参考

ElasticSearch

基于ElasticSearch6.*的基本操作,只涉及基本使用,不包含集群搭建、部署等

扩展后期可能会单独发一些,欢迎关注

创建索引

请求地址 http://localhost:9200/name/  #name为创建索引的名字
PUT /name #put请求,右面是名字
{
    
    
    "settings": {
    
    
       "index": {
    
    
        	"number_of_shards": "2", #分片书
        	"number_of_replicas": "0" #副本数
       }
    }
}

删除索引

请求地址 http://localhost:9200/name/
DELETE /name #DELETE请求,右面是名字

新增数据

http://localhost:9200/索引/类型/id
例:http://localhost:9200/test/user/0001
POST /name/type/id
body:
    {
    
    
      "id":1,
      "name":"李华",
      "age":20,
      "sex":"男"
    }

更新数据

  • 第一种覆盖
http://localhost:9200/test/user/0001
PUT /name/type/id
body:
{
    
    
   "id":1,
    "name":"李华1",
    "age":20,
    "sex":"男" 
}
直接覆盖
  • 第二种局部修改
http://localhost:9200/test/user/0001/_update #注意这里加了_update
POST /name/type/id
body:
{
    
    
    "doc":{
    
    
        "sex":"男" 
    }
}

删除

DELETE /name/type/id
直接执行

获得数据

http://localhost:9200/test/user/0001/
GET /name/type/id
获取多条
http://localhost:9200/test/user/_search #默认返回10,多了需要做分页
按需索引
http://localhost:9200/test/user/_search?q=age:20
DSL搜索
http://localhost:9200/test/user/_search
POST /name/type/_search
{
    
    
    "query":{
    
    
        "match":{
    
    
            "age":20
        }
    }
}
复杂查询(例如:大于30且为男性)
http://localhost:9200/test/user/_search
POST /name/type/_search
{
    
    
  "query": {
    
     #查找
    "bool": {
    
    
      "filter": {
    
      #过滤
        "range": {
    
      #范围
          "age": {
    
       #age属性
            "gt": 30   #大于30
          }
        }
      },
      "must": {
    
     #满足
        "match": {
    
    
          "sex": "男"
        }
      }
    }
  }
}

符号标识	代表含义
gte	       大于或等于
gt	       大于
lte	       小于或等于
lt	       小于
全文检索
http://localhost:9200/test/user/_search
POST /name/type/_search
{
    
    
    "query":{
    
    
        "match":{
    
    
            "name":"张三 李四"
        }
    }
}
高亮显示
http://localhost:9200/test/user/_search
POST /name/type/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "name": "李华1"
    }
  },
  "highlight": {
    
    
    "fields": {
    
    
      "name": {
    
    }
    }
  }
}
会多返回这么一段
"highlight":{
    
    
	"name":[
		"<em>汪</em><em>京</em><em>1</em>"
    ]
}
聚合(分组)
http://localhost:9200/test/user/_search
POST /name/type/_search
以年龄聚合
{
    
    
  "aggs": {
    
    
    "all_interests": {
    
    
      "terms": {
    
    
        "field": "age"
      }
    }
  }
}
多返回了
{
    
    
  "aggregations": {
    
    
    "all_interests": {
    
    
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
    
    
          "key": 18,
          "doc_count": 1
        },
        {
    
    
          "key": 20,
          "doc_count": 1
        }
      ]
    }
  }
}
指定字段查询
http://localhost:9200/test/user/0001?_source=id,name
GET /name/type/id?_source=id,name

返回
{
    
    
  "_index": "test",
  "_type": "user",
  "_id": "0001",
  "_version": 1,
  "found": true,
  "_source": {
    
    
    "name": "李华1",
    "id": 1
  }
}
加_source去掉头
http://localhost:9200/test/user/0001/_source?_source=id,name
{
    
    
  "name": "李华1",
  "id": 1
}

判断文档是否存在

http://localhost:9200/test/user/0002
HEAD /name/type/id

批量操作

批量获得
http://localhost:9200/test/user/_mget  #批量获得
POST /name/type/_mget
{
    
    
    "ids":["id1","id2"]
}
返回结果
{
    
    
  "docs": [
    {
    
    
      "_index": "test",
      "_type": "user",
      "_id": "0001",
      "_version": 1,
      "found": true,
      "_source": {
    
    
        "id": 1,
        "name": "李华1",
        "age": 20,
        "sex": "男"
      }
    },
    {
    
    
      "_index": "test",
      "_type": "user",
      "_id": "1111",
      "found": false #没找到
    }
  ]
}

批量操作添加

http://localhost:9200/test/user/_bulk
POST /name/type/_bulk
创建
{
    
    "create": {
    
    "_index": "test", "_type": "user", "_id": "0003"}}
{
    
    "id": "0003", "name": "李华3", "age": 23, "sex": "男"}
{
    
    "create": {
    
    "_index": "test", "_type": "user", "_id": "0004"}}
{
    
    "id": "0004", "name": "李华4", "age": 23, "sex": "女"}
{
    
    "create": {
    
    "_index": "test", "_type": "user", "_id": "0005"}}
{
    
    "id": "0005", "name": "李华5", "age": 23, "sex": "男"} #这必须要来个回车

删除
{
    
    "delete": {
    
    "_index": "test", "_type": "user", "_id": "0005"}}

性能优化,批量操作数量不是越多越好,操作任务会被放在内存中,请妥善寻找最佳大小

分页

size:结果数,默认10
from:跳过开始的结果数,默认为0  #就是跳过多少个后开始查  
就是从那条开始读,读几条实现分页
GET /_search?size=55条数据
GET /_search?size=5&from=5 跳过5条,就是第二页
GET /_search?size=5&from=10 跳过10条,就是第三页

映射

类型 表示的数据
String string,text,keyword
Whole number byte,short,integer,long
Floating point float,double
Boolean boolean
Date date

Text:会分词,然后进行索引

​ 支持模糊、精确查询

​ 不支持聚合

keyword:不进行分词,直接索引

​ 支持模糊、精确查询

​ 支持聚合

请求地址 http://localhost:9200/name/  #name为创建索引的名字
PUT /name #put请求,右面是名字
{
    
    
    "settings": {
    
    
       "index": {
    
    
        	"number_of_shards": "2", #分片书
        	"number_of_replicas": "0" #副本数
       }
    },
    "mappings": {
    
    
        "person": {
    
    
            "properties": {
    
    
                "name": {
    
    
                    "type": "text"
                },
                "age": {
    
    
                    "type": "integer"
                },
                "mail": {
    
    
                    "type": "keyword"
                },
                "hobby": {
    
    
                    "type": "text"
                    "analyzer": "ik_max_word" #指定分词器
                }
            }
        }
	}
}
GET /name/_mapping

{
    
    
	"test1": {
    
    
		"mappings": {
    
    
			"person": {
    
    
				"properties": {
    
    
					"age": {
    
    
						"type": "integer"
					},
					"hobby": {
    
    
						"type": "text"
					},
					"mail": {
    
    
						"type": "keyword"  
					},
					"name": {
    
    
						"type": "text"     
					}
				}
			}
		}
	}
}

结构化查询

#term 精确查询
主要用于精确匹配那些值,比如数字,日期,布尔值或not_analyzed的字符串(未经分析的文本数据类型)
POST /name/type/_search
{
    
    
    "query":{
    
    
        "term":{
    
    
            "age":18
        }
    }
}
#terms 多匹配精确查询
terms跟term有点类似,单terms允许指定多个匹配条件,如果某个字段指定了多个值,那么文档需要一起做匹配
{
    
    
    "term":{
    
    
        "tag":["search","full_text","nosql"]
    }
}
{
    
    
    "query":{
    
    
        "terms":{
    
    
            "age":[18,20] #注意:匹配而不是范围查询!
        }
    }  
}
#range 范围查询
范围查询
{
    
    
    "query":{
    
    
        "range":{
    
    
            "age":{
    
    
                "gte:17",   # 大于等于17
                "lt":30     # 小于30
            }
        }
    }  
}
gte:大于等于
gt:大于
lte:小于等于
lt:小于
boost:设置查询的推动值(boost),默认为1.0
`时间范围查询`

#exists 存在字段查询
exists查询可以用于查询文档中是否包含指定字段或没有某个`字段`,类似于sql语句中的is_null条件
POST localhost/_search   #不加索引名称也可以
{
    
    
    "query":{
    
    
        "exists":{
    
     #必须包含某个字段
            "field": "age"
        }
    }
}
#match 标准查询
match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到他,
如果你使用match查询一个全文本字段,它会在真正查询之前用分析器match一下查询字段
如果你传入的是数字布尔日期或者not_analyzed字符串时,它将为你提供准确查询
POST /_search  #可以指定索引
{
    
    
    "query":{
    
    
        "match":{
    
    
            "hobby":"fate"
        }
    }
}
#bool 布尔查询
POST /_search
bool查询可以用来合并多个条件查询结果的布尔逻辑,他包含以下操作符:
`must`:多个查询条件的完全匹配 相当于 and
`must_not`:多个查询条件的相反匹配 相当于 not
`should`:至少有一个查询条件匹配 相当于 or
{
    
    
	"query": {
    
    
		"bool": {
    
    
			"must": {
    
    
				"term": {
    
    
					"age": "18" #满足年龄是18就可以返回 
				}
			},
			"must_not": {
    
    
				"term": {
    
    
					"name": "李华" #名字不能是李华 绝对不能是李华
				}
			},
			"should": [{
    
    
					"match": {
    
    
						"hobby": "fate" ,#爱好是fate分词查询
					}
				},
				{
    
    
					"match": {
    
    
						"mail": "[email protected]" #邮箱是这个 两个满足一个就行
					}
				}
			]
		}
	}
}

单独说一下时间的range查询

日期字段的范围

当范围查询运行在日期类型的字段上时,可以通过日期数学指定范围。

GET _search
{
      
      
"query": {
      
      
  "range" : {
      
      
      "date" : {
      
      
          "gte" : "now-1d/d",
          "lt" :  "now/d"
      }
  }
}
}
1234567891011

日期数学与舍入
当使用日期数学将日期舍入到最近的天、月、小时等时,舍入后的日期依赖于范围的边界是否被包含。

向上舍入移动到舍入范围的最后一毫秒,向下舍入移动到舍入范围的第一毫秒。

  • gt:大于舍入的日期,2014-11-18||/M变为2014-11-30T23:59:59.999,即不包括整个月。
  • gte:大于等于舍入的日期,2014-11-18||/M变为2014-11-01,即包括整个月。
  • lt:小于舍入的日期,204-11-18||/M变为2014-11-01,即不包括整个月。
  • lte:小于等于舍入的日期,2014-11-18||/M变为2014-11-30T23:59:59.999,即包含整个月。

范围查询中的日期格式
默认使用设置在日期字段中的format参数解析格式化日期,但是,此参数可以通过在范围查询中设置format参数来进行覆盖。

GET _search
{
      
      
  "query": {
      
      
      "range" : {
      
      
          "born" : {
      
      
              "gte": "01/01/2012",
              "lte": "2013",
              "format": "dd/MM/yyyy||yyyy"
          }
      }
  }
}
123456789101112

范围查询中的时区
通过在日期值中指定时区或使用time_zone参数指定时区,可以转换日期时区。

GET _search
{
      
      
  "query": {
      
      
      "range" : {
      
      
          "timestamp" : {
      
      
              "gte": "2015-01-01 00:00:00", 
              "lte": "now", 
              "time_zone": "+01:00"
          }
      }
  }
}
123456789101112

note:gte参数的日期值将会被转化为2014-12-31T23:00:00 UTC
note:now不会被time_zone参数影响(日期必须存储为UTC)

参考:https://blog.csdn.net/qq_32165041/article/details/83714203

过滤查询

#查询年龄未18岁user   类型通过restful指定
POST /name/type/_search
{
    
    
    "query":{
    
    
        "bool":{
    
    
            "filter":{
    
    
                "term":{
    
    
                    "age":18
                }
            }
        }
    }
}
#注意:
 - 一条查询语句会计算每个文档与查询语句之间的相关性,并给出评分,然后按评分排序
 - 过滤查询会缓存数据,一般过滤查询性能要高于普通查询
 - `建议:做精确查询的时候尽量使用过滤查询,因为过滤查询可以缓存数据`

中文分词

#指定分词器进行分词
POST /_analyze
{
    
    
    "analyze":"standard",
    "text":"fate动漫"
}
`返回`
{
    
    
  "tokens":[
    {
    
    
      "token": "fate",
      "start_offset": 0,
      "end_offset": 4,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
    
    
      "token": "动",
      "start_offset": 4,
      "end_offset": 5,
      "type": "<IDEOGRAPHIC>",
      "position": 1
    },
    {
    
    
      "token": "漫",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<IDEOGRAPHIC>",
      "position": 2
    }
  ]
}
`在做一个测试` #指定索引库,指定字段的text
POST /name/_analyze
{
    
    
    "analyzer":"standard",
    "field":"hobby",
    "text":"fate动漫"
}
#使用ik分词器分词         涉及ik分词器的安装,自行百度
POST /_analyze
{
    
    
    "analyzer":"ik_max_word",
    "text":"中华人民共和国"
}
结果
tokens":[
{
    
    "token": "中华人民共和国", "start_offset": 0, "end_offset": 7, "type": "CN_WORD",},
{
    
    "token": "中华人民", "start_offset": 0, "end_offset": 4, "type": "CN_WORD",},
{
    
    "token": "中华", "start_offset": 0, "end_offset": 2, "type": "CN_WORD",},
{
    
    "token": "华人", "start_offset": 1, "end_offset": 3, "type": "CN_WORD",},
{
    
    "token": "人民共和国", "start_offset": 2, "end_offset": 7, "type": "CN_WORD",},
{
    
    "token": "人民", "start_offset": 2, "end_offset": 4, "type": "CN_WORD",},
{
    
    "token": "共和国", "start_offset": 4, "end_offset": 7, "type": "CN_WORD",},
{
    
    "token": "共和", "start_offset": 4, "end_offset": 6, "type": "CN_WORD",},
{
    
    "token": "国", "start_offset": 6, "end_offset": 7, "type": "CN_CHAR",}
]

全文搜索

- 相关性
- 分词
测试步骤:
	1.创建索引,指定text类型
	2.创建文档 #较占篇幅,自行百度或者看上面的批量操作示例
	3.单词搜索
		POST /name/type/_search
		{
    
    
            "query":{
    
    
                "match":{
    
    
                    "hobby":"鸡蛋,饭"   #可以单个也可以多个,用,号分割,满足其中一个就行
                }
            },
            "highlight":{
    
     #高亮
                "fields":{
    
    
                    "hobby":{
    
    } 
                }
            }
        }
	4.多词搜索
	POST /name/type/_search
    {
    
    
        "query":{
    
    
            "match":{
    
    
                "hobby":{
    
    
                    "query":"西红柿 面",    #用空格分隔
                    "operator":"and"  #表示and ,必须满足连个条件
                }
            }
        },
        "highlight":{
    
     
            "fields":{
    
    
                "hobby":{
    
    } 
            }
        }
    }
    ##注意:and和or都是100%匹配率,因此我们可以自行设置匹配度
	    {
    
    
        "query":{
    
    
            "match":{
    
    
                "hobby":{
    
    
                    "query":"西红柿 面",    #用空格分隔
                    "minimum_should_match":"40%"  #设置40%匹配度
                }
            }
        },
        "highlight":{
    
     
            "fields":{
    
    
                "hobby":{
    
    } 
            }
        }
    }
#组合搜索 
POST /name/type/_search  
 `必须有西红柿,不能包含盖饭,有汤匹配度更高`
{
    
    
    "query":{
    
    
        "bool":{
    
    
            "must":{
    
    
                "match":{
    
       
                "hobby":"西红柿"
                }
            },
            "must_not":{
    
    
                "match":{
    
    
                    "hobby":"盖饭"
                }
            },
            "should":[
                {
    
    
                "match":{
    
    
                    "hobby":"汤"
                }
            }
            ]
        }
    },
    "highlight":{
    
    
        "fields":{
    
    
            "hobby":{
    
    }
        }
    }
}

权重

`必须包含西红柿和鸡蛋,如果是面就给10权重,饭就给2权重`
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": {
    
    
        "match": {
    
    
          "hobby": {
    
    
            "query": "西红柿 鸡蛋",
            "operator": "and"
          }
        }
      },
      "should": [
        {
    
    
          "match": {
    
    
            "hobby": {
    
    
              "query": "面",
              "boost": 10  #设置权重
            }
          }
        },
        {
    
    
          "match": {
    
    
            "hobby": {
    
    
              "query": "饭",
              "boost": 2
            }
          }
        }
      ]
    }
  },
  "highlight": {
    
    
    "fields": {
    
    
      "hobby": {
    
    }
    }
  }
}

猜你喜欢

转载自blog.csdn.net/qq_44769485/article/details/113603530