1.es介绍及作用?

elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容.

2.es和lucene的关系?

  • elasticsearch底层是基于lucene来实现的。
  • Lucene是一个Java语言的搜索引擎类库,是Apache公司的顶级项目,

    3.倒排索引介绍?

    创建倒排索引是对正向索引的一种特殊处理,流程如下:

  • 将每一个文档的数据利用算法分词,得到一个个词条

  • 创建表,每行数据包括词条、词条所在文档id、位置等信息
  • 因为词条唯一性,可以给词条创建索引,例如hash表结构索引

倒排索引的搜索流程如下(以搜索”华为手机”为例):
1)用户输入条件”华为手机”进行搜索。
2)对用户输入内容分词,得到词条:华为、手机。
3)拿着词条在倒排索引中查找,可以得到包含词条的文档id:1、2、3。
4)拿着文档id到正向索引中查找具体文档。
image-20210720201115192.png

4.中文分词器介绍?

IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包,采用了特有的”正向迭代最细粒度切分算法”具有60万字/秒的高速处理能力。优化的词典存储,更小的内存占用。支持用户词典扩展定义

5.如何扩展新词 如何忽略停顿词?

  • 扩展词词典
    • 打开IK分词器config目录:

image-20210506112225508.png

  1. - IKAnalyzer.cfg.xml配置文件内容添加:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 *** 添加扩展词典-->
        <entry key="ext_dict">ext.dic</entry>
</properties>
  - 新建一个 ext.dic,可以参考config目录下复制一个配置文件进行修改,在文档里编写自定义拓展词典.
  - 重启elasticsearch
  • 停用词词典

    • 1)IKAnalyzer.cfg.xml配置文件内容添加:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
      <properties>
      <comment>IK Analyzer 扩展配置</comment>
      <!--用户可以在这里配置自己的扩展字典 *** 添加扩展词典-->
      <entry key="ext_dict">ext.dic</entry>
      <!--用户可以在这里配置自己的扩展停止词字典  *** 添加停用词词典-->
      <entry key="ext_stopwords">stopword.dic</entry>
      </properties>
      
    • 在 stopword.dic 添加停用词

    • 重启elasticsearch

      6.mysql和es 对比?

      es 更关注的是海量数据的搜索,对事务,并发处理一致性的问题没有严格性的要求数据建模也不严格(后续可以随意添加列),mysql对事务,并发处理一致性的问题要求较高,数据的管理放在mysql中管理,负责增删改,需要查询时再将数据存一份到es中,搜索时就无须再访问mysql,如果mysql数据更新,可以使用mq进行监听并同步.

      7.java中如何操作es?

      索引库相关请求需要加Index,文档不需要
  • 索引库的操作

    • 统一的第一步:初始化客户端

      @BeforeEach
      void setUp() {
         client = new RestHighLevelClient(RestClient.builder(
                 HttpHost.create("http://192.168.200.129:9200")
         ));
      }
      
    • 创建索引库

image.png

@Test
    void testCreateIndex() throws IOException {
         // 1. 创建对应操作的请求对象   CreateIndexRequest
        CreateIndexRequest request = new CreateIndexRequest("hotel"); // 索引库名称
        // 设置请求参数
        request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
        // 2. 调用client执行对应请求方法
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        // 3. 解析响应结果
        System.out.println(response.isAcknowledged());
    }
  • 取得索引库(判断索引库是否存在)

    @Test
    void testExistsIndex() throws IOException {
       // 1. 创建对应操作的请求对象
       GetIndexRequest request = new GetIndexRequest("hotel");
       // 设置请求参数
       // 2. 调用client执行对应请求方法
       boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
       // 3. 解析响应结果
       System.out.println(exists ? "索引库已经存在":"索引库不存在");
    }
    
  • 删除索引库

    @Test
    public void deleteIndex() throws IOException {
       // 1. 创建对应操作的请求对象
       DeleteIndexRequest request = new DeleteIndexRequest("hotel");
               // 设置请求参数
       // 2. 调用client执行对应请求方法
       AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
       // 3. 解析响应结果
       System.out.println(response.isAcknowledged());
    }
    
  • 统一最后一步:关闭连接

    /**
    * 关闭客户端
    */
    @AfterEach
    public void closeClient(){
       try {
           client.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
    }
    
  • 文档的操作

    • 统一的第一步:初始化客户端

      @BeforeEach
      void setUp() {
         client = new RestHighLevelClient(RestClient.builder(
                 HttpHost.create("http://192.168.200.129:9200")
         ));
      }
      
    • 添加文档(获取对象后一定转换成json数据)

      @Test
      public void addDocument() throws IOException {
         // 1. 从数据库中  根据id查询一条酒店数据  Hotel
         Hotel hotel = hotelService.getById(38812);
         // 2. 将Hotel转为HotelDoc
         HotelDoc hotelDoc = new HotelDoc(hotel);
         // 3. 将数据添加到索引库
         // 3.1  创建请求对象   IndexRequest
         IndexRequest request = new IndexRequest("hotel");
         //      设置请求参数  id    文档json内容
         request.id(String.valueOf(hotelDoc.getId()));
         //             文档json字符串                指定参数类型json
         request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
         // 3.2 调用client执行对应的方法  index
         IndexResponse response = client.index(request, RequestOptions.DEFAULT);
         // 3.3 得到响应结果
         System.out.println(response.getResult());
      }
      
    • 获取文档

      @Test
      public void getDocumentById() throws IOException {
         // 1. 创建请求
         GetRequest request = new GetRequest("hotel","38812");
         // 2. 执行请求
         GetResponse response = client.get(request, RequestOptions.DEFAULT);
         // 3. 解析响应
         String jsonStr = response.getSourceAsString();
         HotelDoc hotelDoc = JSON.parseObject(jsonStr, HotelDoc.class);
         System.out.println(hotelDoc);
      }
      
    • 修改文档(修改某一个属性,修改全属性使用index方法)

      @Test
      public void updateDocumentById() throws IOException {
         // 1. 创建请求
         UpdateRequest updateRequest = new UpdateRequest("hotel","38812");
         updateRequest.doc("price","698");
         // 2. 执行请求
         UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);
         // 3. 解析响应
         System.out.println(response.getResult());
      }
      
    • 删除文档

      @Test
      public void deleteDocumentById() throws IOException {
         // 1. 创建请求
         DeleteRequest request = new DeleteRequest("hotel","38812");
         // 2. 执行请求
         DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
         // 3. 解析响应
         System.out.println(response.getResult());
      }
      
    • 批量导入(IndexRequest对象不支持复用,需要放在循环里,否则会被覆盖)

      @Test
      public void bulkAddDocuments() throws IOException {
         // 1. 查询出数据库中所有的酒店数据  list集合
         List<Hotel> list = hotelService.list();
         // 2. 创建批处理对象   BulkRequest
         BulkRequest request = new BulkRequest("hotel");
         // 3. 遍历集合
         for (Hotel hotel : list) {
             //     3.1  集合中的每一个Hotel对象  转成 HotelDoc
             HotelDoc hotelDoc = new HotelDoc(hotel);
             //     3.2  创建文档添加请求  IndexRequest
             IndexRequest indexRequest = new IndexRequest();
             indexRequest.id(String.valueOf(hotelDoc.getId()));
             indexRequest.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
             //     3.3  将添加请求 添加到批处理请求中
             request.add(indexRequest);
         }
         // 4. 调用client执行bulk批处理方法
         BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
         // 5. 得到响应结果
         System.out.println(bulk.status());
      }
      
    • 统一最后一步:关闭连接

      /**
      * 关闭客户端
      */
      @AfterEach
      public void closeClient(){
         try {
             client.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
      }