什么是 ElasticSearch (es)?【精通】
- 定义:一个分布式全文搜索引擎
- 功能:
- 数据查询
- 组成:(5个)
- index: 区分不同业务数据,类似mysql的database
- type:区分业务同类型数据,类似mysql的table
- 7.x之后内部默认为_doc
- 6.x一个index只能有一个type
- 5.x一个index可以有一个type
- document:文档数据,类似mysql的row
- 内置_id字段,是文档的唯一主键
- field:文档字段,类似mysql的column
- 倒排索引:词条与文档映射的关系数据
- mapping:是用于映射文档字段、index属性的功能
- 字段属性
- type:指定类型
- analyer:指定存储分词器
- search_analyzer:指定搜索时的分词器
- enabled:是否建立索引
- store:是否可以排序
- 字段属性
ES的访问URL(index)【精通】
-
创建index
PUT http://localhost:9200/索引名称
-
删除index
DELETE http://localhost:9200/索引名称
-
查询index
-
查询单个
GET http://localhost:9200/索引名称1,索引名称2
-
查询所有
GET http://localhost:9200/_all
-
-
关闭index
DELETE http://localhost:9200/索引名称/_close
-
打开index
DELETE http://localhost:9200/索引名称/_open
ES的访问URL(document)【精通】
-
插入
PUT /test1/_doc/[指定唯一id] { "name":"张三", "age":1 }
-
删除
DELETE /test1/_doc/[指定唯一id]
-
查询
GET /test1/_doc/[指定唯一id]
-
修改:与插入使用方式一致
ES内置指令【熟练】
- _close:关闭索引
- _open:打开索引
- _all:查询所有索引
- _analyze:测试分词结果
ES文档字段的数据类型
- text:字符串,类似String,分词不支持聚合
- keyword:字符串,类似String,不分词支持聚合
- 复合类型:
- 对象:当前document的子文档
- 数组
IK分词器
-
安装
-
把ik的编译文件拷贝到plugins目录下即可
https://github.com/medcl/elasticsearch-analysis-ik/releases
-
-
ik分词器的名称
- ik_smart:粗粒度,一般用于存储时的内容分词
- ik_max_work:细粒度,一般用于搜索条件的分词
Docker cp命令【精通】
- 从主机拷贝到容器 docker cp ./ik es:/usr/share/elasticsearch/plugins
- 从容器拷贝到主机 docker cp es:/usr/share/elasticsearch/plugins /opt
查询的方式【精通】
- term:完全匹配,类似mysql的等于=
- match:分词后再进行分别词条搜索,最后取并集
SpringBoot整合原生ESAPI【熟练】
- 导包
-
配置
-
编码
@Bean public RestHighLevelClient client(){ return new RestHighLevelClient(RestClient.builder( new HttpHost( host, port, "http" ) )); }
创建索引
//1.使用client获取操作索引的对象
IndicesClient indicesClient = client.indices();
//2.具体操作,获取返回值
CreateIndexRequest createRequest = new CreateIndexRequest("itheima");
CreateIndexResponse response = indicesClient.create(createRequest, RequestOptions.DEFAULT);
//3.根据返回值判断结果
System.out.println(response.isAcknowledged());
查询索引
IndicesClient indices = client.indices();
GetIndexRequest getReqeust = new GetIndexRequest("itcast");
GetIndexResponse response = indices.get(getReqeust, RequestOptions.DEFAULT);
删除索引
IndicesClient indices = client.indices();
DeleteIndexRequest deleteRequest = new DeleteIndexRequest("itheima");
AcknowledgedResponse response = indices.delete(deleteRequest, RequestOptions.DEFAULT);
添加文档
Map data = new HashMap();
data.put("address","北京昌平");
data.put("name","大胖");
data.put("age",20);
//1.获取操作文档的对象
IndexRequest request = new IndexRequest("itcast").id("1").source(data);
//添加数据,获取结果
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
//打印响应结果
System.out.println(response.getId());
查询单条数据
GetRequest getReqeust = new GetRequest("itcast","1");
//getReqeust.id("1");
GetResponse response = client.get(getReqeust, RequestOptions.DEFAULT);
//获取数据对应的json
System.out.println(response.getSourceAsString());
删除单条数据
DeleteRequest deleteRequest = new DeleteRequest("itcast","1");
DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(response.getId());
批量操作指令_bulk
-
API
//创建bulkrequest对象,整合所有操作 BulkRequest bulkRequest = new BulkRequest(); /* # 1. 删除1号记录 # 2. 添加6号记录 # 3. 修改3号记录 名称为 “三号” */ //添加对应操作 //1. 删除1号记录 DeleteRequest deleteRequest = new DeleteRequest("person","1"); bulkRequest.add(deleteRequest); //2. 添加6号记录 Map map = new HashMap(); map.put("name","六号"); IndexRequest indexRequest = new IndexRequest("person").id("6").source(map); bulkRequest.add(indexRequest); Map map2 = new HashMap(); map2.put("name","三号"); //3. 修改3号记录 名称为 “三号” UpdateRequest updateReqeust = new UpdateRequest("person","3").doc(map2); bulkRequest.add(updateReqeust); //执行批量操作 BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT); RestStatus status = response.status(); System.out.println(status);
查询方式【精通】
matchAll:查询所有的数据
GET /test2/_search
{
"query": {
"match_all": {}
},
"from": 0, //分页起始位置
"size": 20 //分页大小
}
{
"took" : 1,// 耗时(毫秒)
"timed_out" : false, //是否超时
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {// 查询的结果集
"total" : {// 总数
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,//最大评分
"hits" : [// 数据列表
{
"_index" : "test2",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {// 它是数据document的json内容
"name" : "张三",
"age" : "1"
}
}
]
}
}
-
// 拼装条件,指定搜索所以+查询条件+分页条件 SearchRequest request = new SearchRequest("test2"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(QueryBuilders.matchAllQuery()); builder.from(0); builder.size(20); builder.sort("age",SortOrder.DESC);// 排序 request.source(builder); // 执行查询 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 解析结果 SearchHits hits = response.getHits(); long total = hits.getTotalHits().value; // Arrays.asList( hits.getHits()) 吧数组转成List对象 // Arrays.asList( hits.getHits()).stream().map 是对象的转换函数,把A对象转成B对象 List<Goods> list = Arrays.asList( hits.getHits()).stream().map(hit->{ String json = hit.getSourceAsString(); System.out.println(json); try { return objectMapper.readValue(json,Goods.class); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; }).collect(Collectors.toList()); Result result = new Result(); Map<String,Object> data = new HashMap<>(); data.put("total",total); data.put("data",list); result.setStatus(0); result.setData(data);
Term:精确查询
搜索关键字不分词与字段内容完全匹配,就是等号
GET _search
{
"query": {
"term": {
"name": {
"value": "张三"
}
}
}
}
TermQueryBuilder query = QueryBuilders.termQuery("name","张三");
Match:模糊查询
分词之后,可以求并集或者交集
// A:1、2、3 B:1、2、5
// operator:or并集=1、2、3、5
// operator:and交集=1、2
GET _search
{
"query": {
"match": {
"name": {
"query": "张三",
"operator": "or"
}
}
}
}
MatchQueryBuilder query = QueryBuilders.matchQuery("name", "张三").operator(Operator.AND);
Wildcard:通配符查询
就是like查询,?是单个字符,*是任意字符。注意竟可能星号不要写在前面
GET _search
{
"query": {
"wildcard": {
"name": {
"value": "张?"
}
}
}
}
WildcardQueryBuilder query = QueryBuilders.wildcardQuery("name", "张?");
Regexp:正则查询
查询的字段使用正则表达式
GET _search
{
"query": {
"regexp": {
"name": "[张](.)*"
}
}
}
RegexpQueryBuilder query = QueryBuilders.regexpQuery("name", "张(.)*");
Prefix:前缀查询
查询以某个关键词开头的数据
GET _search
{
"query": {
"prefix": {
"name": "张"
}
}
}
PrefixQueryBuilder query = QueryBuilders.prefixQuery("name", "张");
Range:范围查询
GET _search
{
"query": {
"range": {
"age": {
"gte": 1,
"lte": 20
}
}
}
}
RangeQueryBuilder query = QueryBuilders.rangeQuery("age").gte(1).lte(10);
QueryString:表达式查询
- 对多个字段和条件进行组合查询,并默认取交集
- 对于输入的关键字会进行分词
GET _search
{
"query": {
"query_string": {
"query": "name:张二 AND age:1"
}
}
}
QueryStringQueryBuilder query = QueryBuilders.queryStringQuery("name:张二 AND age:1");
SimpleQueryString:多字段条件查询
- 对多个字段查询
- 对于输入的关键字不会进行分词
GET _search
{
"query": {
"simple_query_string": {
"fields": ["name","age"],
"query": "name:张二 AND age:1"
}
}
}
Bool:组合条件查询
只组合其它搜索条件,无自己的特殊条件
- 组合方式
- must:执行查询,并计算评分
- filter:执行查询,不计算评分
GET _search
{
"query": {
"bool": {
"must": [
{
"term": {
"name": {
"value": "张三"
}
}
}
],
"filter": {
"range": {
"age": {
"gte": 1,
"lte": 20
}
}
}
}
}
}
TermQueryBuilder term = QueryBuilders.termQuery("name","张三");
WildcardQueryBuilder wildcard = QueryBuilders.wildcardQuery("name", "张?");
BoolQueryBuilder query = QueryBuilders.boolQuery();
query.must(term);
query.filter(wildcard);
builder.query(query);