ES语法学习

Kibanan语法:

GET _search
{
  "query": {
    "match_all": {}
  }
}

GET /

#测试分词器 ik_max_word  ik_smart
POST /_analyze
{
  "text": "黑马程序员学习java太棒了",
  "analyzer": "ik_max_word"
}

POST /_analyze
{
  "text":"传智播客的课程可以白嫖,而且就业率高达95%,奥力给",
  "analyzer": "ik_smart"
}


#创建索引库
PUT /heima
{
  "mappings": {
    "properties": {
      "info":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "email":{
        "type": "keyword",
        "index": false
      },
      "name":{
        "type": "object",
        "properties": {
          "firstName":{
            "type":"keyword"
          },
          "lastName":{
            "type":"keyword"
          }
        }
      }
    }
  }
}

#查询索引库
GET /heima

#删除索引库
DELETE /heima

#修改索引库  (只能添加字段)
PUT /heima/_mapping
{
  "properties":{
    "age":{
      "type":"long"
    }
  }
}

#插入数据
POST /heima/_doc/1
{
  "info":"黑马程序员java讲师",
  "email":"1142@qq.com",
  "name":{
    "firstName":"云",
    "lastName":"赵"
  }
}
#查询文档
GET /heima/_doc/1

#删除文档
DELETE /heima/_doc/1

#全量修改文档  (id不存在变成新增)
PUT /heima/_doc/1
{
  "info":"黑马程序员java讲师",
  "email":"dfl@qq.com",
  "name":{
    "firstName":"云",
    "lastName":"赵"
  }
}

#增量修改
POST /heima/_update/1
{
  "doc": {
    "email":"dfl999@qq.com"
  }
}



PUT /hotel
{
  "mappings": {
    "properties":{
      "id":{
        "type":"keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address":{
        "type":"keyword",
        "index": false
      },
      "price":{
        "type":"integer"
      },
      "score":{
        "type":"integer"
      },
      "brand":{
        "type":"keyword",
         "copy_to": "all"
      },
      "city":{
        "type": "keyword"
      },
      "starName":{
        "type":"keyword"
      },
      "business":{
        "type":"keyword",
        "copy_to": "all"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type":"text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

GET /hotel

DELETE /hotel

#查询数据
GET /hotel/_doc/61083

#批量查询数据
GET /hotel/_search

GET /hotel/_search
{
  "query":{
    "match_all": {}
  }
}

#一:全文检索查询  match查询一个字段
GET /hotel/_search
{
  "query":{
    "match": {
      "all": "外滩如家"
    }
  }
}

#通过使用all和下面的多个字段搜索是一样的,那么使用那个呢?参与搜索的字段越多查询效率越低推荐使用all的方法
#全文检索查询  match查询多个字段
GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query": "外滩如家",
      "fields": ["brand","name","business"]
    }
  }
}

#二:精确查询  查询的条件它也不需要分词,而且搜索条件要和查找的字段值完全匹配
# 精确查询一般查找keyword、数值、日期、boolean等字段,不会对搜索的字段分词
#分为term:精确值查询  range:范围查询值
GET /hotel/_search
{
  "query":{
    "term": {
      "city": {
        "value": "上海"
      }
    }
  }
}

GET /hotel/_search
{
  "query":{
    "range": {
      "price": {
        "gte": "100",
        "lte": 300
      }
    }
  }
}
 
#三:地理查询  查询距离中心点15公里的所有值
GET /hotel/_search
{
  "query":{
    "geo_distance":{
      "distance":"15km",
      "location":"31.21,121.5"
    }
  }
}
 
#geo_bounding_box   查询值落在矩形范围内的所有文档
GET /hotel/_search
{
  "query":{
    "geo_bounding_box":{
      "location":{
        "top_left":{
          "lat":31.1,
          "lon":121.5
        },
        "bottom_right":{
          "lat":30.9,
          "lon":121.7
        }
      }
    }
  }
}

#三:复合查询
#相关性算分 function_score:算分函数查询,控制文档的相关性算分,控制文档排名
#算分函数的结果functory_score会与query_score运算得到新的算分 weight:给一个常量值作为函数结果,field_value_factor文档中的某个字段值作为函数结果,random_score:随机生成一个值作为函数结果,script_score:自定义公式,作为函数结果
# filter 过滤条件复合条件的才会重新算分
#boost_mode:算分函数的结果functory_score会与query_score运算方式:加权模式默认multiply 两者相乘,replace:用functory_score替换query_score,其他sum、avg、max、min
GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "match":{
          "all":"外滩"
        }
      },
      "functions": [
        {
          "filter": {
            "term":{
              "brand":"如家"
            }
          },
          "weight": 10
        }
      ],
      "boost_mode": "sum"
    }
  }
}

#复合查询
#Boolean Query:不是计算相关性算分,而是把多个查询语句组合在一起,形成新的查询,被组合的查询称为子查询
# must_not和filter 不参与算分  果子查询较多,都参与算分,会非常影响性能
# ES会把filer的查询,放到缓存里面,将来在查询的时候,会近一步提高性能
# 除了跟算分相关的,一般是关键字,放到must和should里面
# 其他的都应该放到must_not和filter里面,尽可能的减少算分提高查询的效率

# 搜索框的内容关键字的搜索可以放到must里,因为它参与算分 品牌也好价格也好,放到must_not或者filter里面,放到这里面不参与算分
# must:必须匹配每个子查询类似与 should:选择性匹配子查询类似或 must_not:必须不匹配不参与算分类似非 filter:必须匹配,不参与算分

#查询名字包含如家,价格不高于400。坐标在31.21,121.5的范围内的
GET /hotel/_search
{
  "query":{
    "bool":{
      "must": [
        {
          "match": {
             "name": "如家"
          }
        }
      ],
      "must_not": [
        {
          "range":{
            "price": {
              "gt": 400
            }
          }
        }
      ],
      "filter": [
        {
          "geo_distance":{
            "distance": "10km",
            "location": {
              "lat": 31.21,
              "lon": 121.5
            }
          }
        }
      ]
    }
  }
}


#排序  默认是根据算分的score来排序的,可以排序的字段有keyword  一旦进行了排序_score就没有值了
GET /hotel/_search
{
  "query":{
    "match_all": {}
  },
  "sort":[
    {
      "_geo_distance":{
        "location":"31.21,121.5",
        "order":"asc",
        "unit":"km"
      }
    }
  ]
}

#根据用户评价降序排序,评价相同按照价格排序
GET /hotel/_search
{
  "query":{
    "match_all": {}
  },
  "sort": [
    {
      "score": {
        "order": "desc"
      },
      "price":{
        "order": "asc"
      }
    }
  ]
}

# 查询按照指定坐标的距离升序排序
GET /hotel/_search
{
  "query":{
    "match_all": {}
  },
  "sort":[
    {
      "_geo_distance":{
        "location":{
          "lat": 31.21,
          "lon": 121.5
        },
        "order":"asc",
        "unit":"km"
      }
    }
  ]
}




#分页 ,ES底层采用倒排索引,它的结构是不利于做分页的,实际上采用的是逻辑上的分页,比如查990到1000的数据,对ES来讲它或查询0到1000的所有数据,然后去截取990-1000的部分
GET /hotel/_search
{
  "query":{
    "match_all": {}
  },
  "sort":[
    {
       "price":"asc"
    }
  ],
  "from":20,
  "size":10
}

# 会产生深度分页问题
GET /hotel/_search
{
  "query":{
    "match_all": {}
  },
  "sort":[
    {
       "price":"asc"
    }
  ],
  "from":9991,
  "size":10
}

# 高亮
# ES搜索的字段必须与高亮的字段必须一致,如果不一致,需要添加require_field_match 默认是高亮字段和搜索字段匹配 
GET /hotel/_search
{
  "query":{
    "match":{
      "all":"如家"
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "require_field_match": "true"
      }
    }
  }
}

#如果不一致,需要添加require_field_match:false
GET /hotel/_search
{
  "query":{
    "match":{
      "brand":"如家"
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "require_field_match": "false",
        "pre_tags": "<em>",
        "post_tags": "</em>"
      }
    }
  }
}

#搜索处理的整体语句
GET /hotel/_search
{
  "query":{
    "match":{
      "name":"如家"
    }
  },
  "from":0, 
  "size": 20,
  "sort":[
    {
      "price":"asc"
    },
    {
      "_geo_distance": {
        "location": "31.21,121.5",
        "order": "asc",
        "unit": "km"
      }
    }
  ],
  "highlight": {
    "fields": {
      "name": {
       
        "pre_tags": "<em>",
        "post_tags": "</em>"
      }
    }
  }
}

Idea操作ES:

package cn.itcast.hotel;

import cn.itcast.hotel.constants.HotelIndexConstants;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.List;
import java.util.Map;


@SpringBootTest
class HotelIndexTestCopy {

    private RestHighLevelClient client;

    //单元测试里面的注解,提前完成对象的初始化
    @BeforeEach
    void setUp(){
        this.client=new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.73.129:9200")));
    }

    //销毁注解
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }


    //所有的单元测试,都会先运行BeforeEach 最后运行@AfterEach
    @Test
    void testInit(){
        System.out.println(client+"===================");
    }


    //创建表
    @Test
    void createHotelIndex() throws IOException {
        //1.创建Request对象
        CreateIndexRequest request=new CreateIndexRequest("hotel");
        //2.准备请求的参数DSL语句
        request.source(HotelIndexConstants.MAPPING_TEMPLATE,XContentType.JSON);
        //3.发送请求   client.indices()返回值是IndicesClient对象里面封装了操作索引库的API
        client.indices().create(request,RequestOptions.DEFAULT);
    }

    //删除表
    @Test
    void testDeleteHotelIndex() throws IOException {
        //1.创建Request对象
        DeleteIndexRequest request=new DeleteIndexRequest("hotel");
        //发起请求
        client.indices().delete(request,RequestOptions.DEFAULT);
    }

    //判断表是否存在
    @Test
    void testExistHotelIndex() throws IOException {
        //1.创建Request对象
        GetIndexRequest request=new GetIndexRequest("hotel");
        //发起请求
        boolean exist=client.indices().exists(request,RequestOptions.DEFAULT);
        System.out.println(exist ? "表存在!":"表不存在!");
    }

    @Autowired
    private IHotelService hotelService;

    //添加数据
    @Test
    void addDocumen() throws IOException {
        //根据id查询酒店数据
        Hotel hotel=hotelService.getById(61083);
        System.out.println(hotel);

        //转换对象类型
        HotelDoc hotelDoc=new HotelDoc(hotel);
        System.out.println(hotelDoc);

        //准备request对象
        IndexRequest request=new IndexRequest("hotel").id(hotel.getId().toString());
        //准备json数据
        request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
        //发送请求  client.index() :index表示给文档创建倒排索引
        client.index(request,RequestOptions.DEFAULT);
        System.out.println("新增文档成功!");

    }


    //查询数据 根据id查询数据
    @Test
    void selectDocumen() throws IOException {
        //创建request
        GetRequest request=new GetRequest("hotel","61083");
        //发送请求得到结果
        GetResponse response=client.get(request,RequestOptions.DEFAULT);
        //解析结果
        String json=response.getSourceAsString();
        System.out.println("解析的json数据:"+json);

        //利用JSON反序列化为java对象
        HotelDoc hotelDoc=JSON.parseObject(json,HotelDoc.class);
        System.out.println("转化的java对象:"+hotelDoc);
    }


    //更新数据
    @Test
    void updateDocument() throws IOException {
        //创建request
        UpdateRequest request=new UpdateRequest("hotel","61083");
        //准备参数
        request.doc(
          "price","666",
                "startName","四钻"
        );
        //发送请求
        client.update(request,RequestOptions.DEFAULT);
        System.out.println("更新成功");
    }

    //删除数据
    @Test
    void deleteDocumen() throws IOException {
        //创建request
        DeleteRequest request=new DeleteRequest("hotel","61083");
        //发送请求
        client.delete(request,RequestOptions.DEFAULT);
        System.out.println("删除数据成功");
    }


    //批量添加数据
    @Test
    void insertBulk() throws IOException {

        //批量查询数据
        List<Hotel> hotels=hotelService.list();

        //创建Bulk请求
        BulkRequest request=new BulkRequest();

        //准备参数  添加多个新增的Request
        for (Hotel hotel:hotels){
            //转换java类型
            HotelDoc hotelDoc=new HotelDoc(hotel);
            //创建新增文档的Request
            request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc),XContentType.JSON));
        }
        //发送请求
        client.bulk(request,RequestOptions.DEFAULT);

        System.out.println("批量添加成功!");

    }


    /**
     * @description:  DSL查询分类DSL查询分类  es检索数据
     * @param: null
     * @return:
     * @author Administrator
     * @date: 2025/3/8 14:03
     */

    //查询数据  查询所有  DSL是通过HightLevelRestClient 中的source()来实现的,里面包含了查询、排序、分页、高亮
    //QueryBuilders 里面包含了各种查询方法
    @Test
    void MallAll() throws IOException {
        //准备request
        SearchRequest request=new SearchRequest("hotel");
        //组织DSL参数
        request.source()
                .query(QueryBuilders.matchAllQuery());
        //发送请求,得到响应结果
        SearchResponse response=client.search(request,RequestOptions.DEFAULT);
        System.out.println("返回的数据"+response);

        //解析结果
        handResponse(response);
    }


    //查询数据  全文检索查询  match_query  multi_match_query
    @Test
    void Match() throws IOException {
        //准备request
        SearchRequest request=new SearchRequest("hotel");
        //组织DSL参数
        request.source()
                .query(QueryBuilders.matchQuery("all","如家"));

        //multi_match_query
        //request.source().query(QueryBuilders.multiMatchQuery("如家","name","business"));

        //发送请求,得到响应结果
        SearchResponse response=client.search(request,RequestOptions.DEFAULT);
        System.out.println("返回的数据"+response);

        //解析响应方法封装
        handResponse(response);
    }


    //查询数据  精确查询  term  range
    @Test
    void termMatch() throws IOException {
        //准备request
        SearchRequest request=new SearchRequest("hotel");
        //组织DSL参数
        request.source()
                .query(QueryBuilders.termQuery("city","上海"));

        //range
        //request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(150));

        //发送请求,得到响应结果
        SearchResponse response=client.search(request,RequestOptions.DEFAULT);
        System.out.println("返回的数据"+response);

        //解析响应方法封装
        handResponse(response);
    }


    //查询数据  复合查询  bool
    @Test
    void Bool() throws IOException {
        //准备request
        SearchRequest request=new SearchRequest("hotel");
        //组织DSL参数
        BoolQueryBuilder boolQuery=new BoolQueryBuilder();
        //添加term
        boolQuery.must(QueryBuilders.termQuery("city","上海"));
        //添加range
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(300));


        request.source().query(boolQuery);

        //发送请求,得到响应结果
        SearchResponse response=client.search(request,RequestOptions.DEFAULT);
        System.out.println("返回的数据"+response);

        //解析响应方法封装
        handResponse(response);
    }


    //排序、分页
    @Test
    void testPageAndSort() throws IOException {
        //页面,每页大小
        int page=1,size=5;
        //准备request
        SearchRequest request=new SearchRequest("hotel");

        //组织DSL参数
        request.source()
                .query(QueryBuilders.matchAllQuery());

        //排序
        request.source().sort("price", SortOrder.ASC);
        //分页
        request.source().from((page-1)*size).size(5);

        //发送请求,得到响应结果
        SearchResponse response=client.search(request,RequestOptions.DEFAULT);
        System.out.println("返回的数据"+response);

        //解析结果
        handResponse(response);

    }

    //解析方法
    private static void handResponse(SearchResponse response) {
        //解析结果
        SearchHits searchHits= response.getHits();
        //查询总条数
        Long total=searchHits.getTotalHits().value;
        System.out.println("共搜索到"+total+"条数据");
        //查询结果数组
        SearchHit[] hits=searchHits.getHits();
        for(SearchHit hit: hits){
            //得到json
            String json=hit.getSourceAsString();
            System.out.println("json数据:"+json);
        }
    }


    //高亮显示
    @Test
    void Heighlight() throws IOException {
        //准备request
        SearchRequest request=new SearchRequest("hotel");
        //组织DSL参数
        request.source()
                .query(QueryBuilders.matchQuery("all","如家"));
        //高亮
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        //发送请求,得到响应结果
        SearchResponse response=client.search(request,RequestOptions.DEFAULT);
        System.out.println("返回的数据"+response);

        //解析结果
        handResponseHighLight(response);
    }


    //解析方法
    private static void handResponseHighLight(SearchResponse response) {
        //解析结果
        SearchHits searchHits= response.getHits();
        //查询总条数
        Long total=searchHits.getTotalHits().value;
        System.out.println("共搜索到"+total+"条数据");
        //查询结果数组
        SearchHit[] hits=searchHits.getHits();
        for(SearchHit hit: hits){
            //得到json
            String json=hit.getSourceAsString();
            System.out.println("json数据:"+json);

            //反序列化
            HotelDoc hotelDoc=JSON.parseObject(json,HotelDoc.class);
            //获取高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)){
                //根据字段名获取高亮结果
                HighlightField highlightField=highlightFields.get("name");
                if (highlightField!=null){
                    //获取高亮
                    String name=highlightField.getFragments()[0].string();
                    //覆盖不高亮的字段
                    hotelDoc.setName(name);
                }
            }
            System.out.println("hotelDoc:"+hotelDoc);

        }
    }


}
相关推荐
虾球xz1 小时前
游戏引擎学习第147天
数据库·学习·游戏引擎
网络安全King2 小时前
学习网络安全需要哪些基础?
学习
dankokoko2 小时前
OPENGLPG第九版学习 -颜色、像素和片元 PART1
学习
岱宗夫up3 小时前
【Python】Django 中的算法应用与实现
数据库·python·opencv·django·sqlite
虾球xz4 小时前
游戏引擎学习第146天
学习·ffmpeg·游戏引擎
cape_NO_75 小时前
运动控制卡--概述学习
学习·自动化
飞向星河6 小时前
SV学习笔记——数组、队列
笔记·学习·c#
胡西风_foxww7 小时前
中学学习难点管理思维魔方
学习·中学·难点
Moonnnn.7 小时前
51单片机——程序执行过程(手工汇编)
汇编·笔记·嵌入式硬件·学习·51单片机