基于狂神说ElasticSearch中操作的总结笔记

ElasticSearch安装

声明 : JDK1.8!ElasticSearch 客户端,界面工具!

基于Java开发,ElasticSearch的版本和Java的核心jar包对应着!

下载地址

官网:https://www.elastic.co/cn/

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

下载地址:https://www.elastic.co/cn/downloads/elasticsearch

在这里是安装windows版的

1、解压

在这里插入图片描述

2、熟悉目录

bin		启动文件
config	配置文件
	log4j2.properties	日志配置文件
	jvm.options			java 虚拟机相关的配置
	elasticsearch.yml	elasticsearch 的配置文件! 默认端口9200
lib		相jar包
logs	日志
modules	功能模块
plugins	插件

3、启动,访问9200

在这里插入图片描述

4、访问测试

在这里插入图片描述

安装可视化界面elasticsearch head

1、下载地址https://github.com/NavyShu/Elasticsearch-Head

需要有配置node环境

2、启动

npm install
npm run start

3、连接测试发现,存在跨域问题:配置ElasticSearch

http.cors.enabled: true
http.cors.allow-origin: "*"

在这里插入图片描述

在这里插入图片描述

4、重启Elasticserach,然后再次连接

在这里插入图片描述

安装Kibanna

官网:https://www.elastic.co/cn/kibana/

Kibanna版本要和ElasticSearch一致!

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

下载完后,解压需要一些时间!

好处 : ELK基本上都是拆箱即用!

启动测试:

1、解压后的目录

在这里插入图片描述

2、启动

在这里插入图片描述

3、访问

在这里插入图片描述

4、开发工具!(Post、curl、head、谷歌浏览器测试!)

在这里插入图片描述

在这里插入图片描述

我们之后的所有操作都在在这里编写的!

5、汉化!

i18n.locale: "zh-CN"

在这里插入图片描述

重新启动Kibana

在这里插入图片描述

IK分词器插件

1、下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases

2、下载完毕后,放入到我们的elasticsearch插件即可!

在这里插入图片描述

3、重启观察elasticsearch,可以看到ik分词器被加载了!

在这里插入图片描述

4、elasticsearch-plugin 可以通过这个命令来查看记载进来的插件

在这里插入图片描述

5、使用kibana测试!

查看不同的分词效果

其中 ik_smart 为最少切分

在这里插入图片描述

ik_max_word为最细粒度划分!穷尽词库的可能!字典

在这里插入图片描述

我们输入超级喜欢狂神说Java

在这里插入图片描述

发现问题:狂神说被拆开了

这种自己需要的词,需要自己加到我们的分词器的字典中!

ik 分词器增加自己的配置!

在这里插入图片描述

重启elasticsearch

在这里插入图片描述

再次测试一下狂神说,看下效果!

在这里插入图片描述

我们需要自己配置分词的时候就可以自定义dic文件然后去配置即可!

Rest风格说明

一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要是用于客户端和服务器交互的软件。基于这个风格设计的软件更简洁,更有层次,更易于实现缓存等机制。

methodurl地址描述
PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)
POSTlocalhost:9200/索引名称/类型名称创建文档(随机文档id)
POSTlocalhost:9200/索引名称/类型名称/文档id/_update修改文档
DELETElocalhost:9200/索引名称/类型名称/文档id删除文档id
GETlocalhost:9200/索引名称/类型名称/文档id查询文档(通过文档id)
POSTlocalhost:9200/索引名称/类型名称/_search查询所有数据

关于索引的基本操作

1、创建一个索引!

PUT /索引名/~类型名~/文档id
{请求体}

在这里插入图片描述

完成了自动增加索引!数据也成功添加了!

在这里插入图片描述

3、字段类型

  • 字符串类型:text、keyword
  • 数值类型:long、integer、short、byte、double、float、half float、scaled float
  • 日期类型:date
  • te布尔值类型:boolean
  • 二进制类型:binary

等等…

4、指定字段的类型

PUT /test2
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text"
      },
      "age":{
        "type": "long"
      },
      "birthday":{
        "type": "date"
      }
    }
  }
}

在这里插入图片描述

获得这个规则!可以通过GET请求获取具体信息!

在这里插入图片描述

5、查看默认的信息!

在这里插入图片描述

在这里插入图片描述

如果自己的文档字段没有指定,那么elasticsearch就会给我吗默认配置字段类型!

扩展:通过命令elasticsearch索引情况!通过GET _cat可以获得elasticsearch当前的很多信息!

在这里插入图片描述

修改 提交使用PUT覆盖值或者使用POST修改!

使用PUT覆盖的方法
在这里插入图片描述

使用POST修改的方法

在这里插入图片描述

删除索引!

在这里插入图片描述

通过DELETE命令实现删除、根据你的请求来判断是还是删除文档记录!

#删除索引
DELETE /索引名称
#删除文档记录
DELETE /索引名称/类型名称/文档id

使用RESTFUL风格是Elasticsearch推荐大家使用的!

关于文档的基本操作(重点)

基本操作

1、添加数据

PUT /me/user/1
{
  "name": "me",
  "age": 1,
  "desc": "一顿操作猛如虎,一看工资2500",
  "tage": ["技术宅","温暖","直男"]
}

在这里插入图片描述

2、获取数据 GET

在这里插入图片描述

3、更新数据 PUT

在这里插入图片描述

4、POST _update,推荐使用这种更新方式!

在这里插入图片描述

简单的搜索!

GET me/user/1

简单的条件查询!

在这里插入图片描述

在这里插入图片描述

复杂操作搜索 select (排序, 分页, 高亮, 模糊查询, 精确查询!)

在这里插入图片描述

在这里插入图片描述
输出结果,不想要那么多!

GET me/user/_search
{
  "query": {
    "match_phrase": {
      "name": "狂神"
    }
  },
  "_source": ["name","desc"]
}

在这里插入图片描述

我们之后使用Java操作ElasticSearch,所有的方法和对象都是这里面的key!

排序

  • asc : 降序
  • desc : 升序

在这里插入图片描述

在这里插入图片描述

分页查询

"from": 从第几个数据开始
"size": 返回多少个数据(单页数据)

在这里插入图片描述

数据下标是从0开始的,和学的所有数据结构是一样的!!!

/search/{current}/{pagesize}

布尔值查询

GET me/user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "狂神说"
          }
        },
        {
          "match": {
            "age": 23          
          }
        }
      ]
    }
  }
}

must(and),所有的条件都要符合比如Sql语句中 where id = 1 and name = xxx

在这里插入图片描述

should(or),所有的条件都要符合比如Sql语句中 where id = 1 or name = xxx

在这里插入图片描述

must_not (not)

在这里插入图片描述

过滤器 filter

在这里插入图片描述

  • gt 大于
  • gte 大于等于
  • lt 小于
  • lte 小于等于

在这里插入图片描述

匹配多个条件

在这里插入图片描述

精确查询

term 查询是直接通过倒排索引指定的词条进程去精确查找的!

关于分词:

  • term ,直接查询精确的
  • match ,会使用分词器解析!(先分析文档,然后在通过分析的文档进行查询!)

两个类型 text keyword

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

多个值匹配的精确查询

在这里插入图片描述

高亮查询

在这里插入图片描述

在这里插入图片描述

这些其实MySQL页可以做,只是MySQL效率比较低!

  • 匹配
  • 按照条件匹配
  • 精确匹配
  • 区间范围匹配
  • 匹配字段过滤
  • 多条件查询
  • 高亮查询

集成SpringBoot

找官方文档

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1、找到原生的依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.15.2</version>
</dependency>

2、找对象

在这里插入图片描述

3、分析这个类中的方法即可!

配置基本的项目

一定要保证我们导入的依赖和我们的es版本一致

本人用的SpringBoot版本是2.6.1 ElasticSearch版本是7.15.2

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如果出现版本不一致需要自定义版本使和ElasticSearch版本一致

在这里插入图片描述

配置一个Config

@Configuration
public class ElasticSearchClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                    				//   IP         端口   协议
                        new HttpHost("127.0.0.1", 9200, "http")));
        return client;
    }
}

// 可以配置多个或单个ElasticSearch
// 官方的配置代码
RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
                new HttpHost("localhost", 9200, "http"),
                new HttpHost("localhost", 9201, "http")));

官方配置代码地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-initialization.html

在这里插入图片描述

具体API测试

1、创建索引

2、判断索引是否存在

3、删除索引

4、创建文档

5、操作文档

    @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient client;

    // 测试索引的创建
    @Test
    void testCreateIndex() throws IOException {
        // 1. 创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("me_index");
        // 2、客户端执行请求 IndicesClient,请求后获得响应
        CreateIndexResponse createIndexResponse =
                client.indices().create(request, RequestOptions.DEFAULT);

        System.out.println(createIndexResponse);
    }

    // 测试获取索引,判断其是否存在
    @Test
    void testExistIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("me_index");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    // 测试删除索引
    @Test
    void testDeleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("me_index");
        // 删除
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.isAcknowledged());
    }

    // 测试添加文档
    @Test
    void testAddDocument() throws IOException {
        // 创建对象
        User user = new User("狂神说", 3);
        // 创建亲求
        IndexRequest request = new IndexRequest("me_index");

        // 规则 PUT /me_index/_doc/1
        request.id("1");
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");

        // 将我们的数据放入请求  json
        request.source(JSON.toJSONString(user), XContentType.JSON);

        // 客户端发送请求,获得响应结果
        IndexResponse index = client.index(request, RequestOptions.DEFAULT);

        System.out.println(index);
        System.out.println(index.status());
    }

    // 获取文档,判断是否存在
    @Test
    void testIsExists() throws IOException {
        GetRequest getRequest = new GetRequest("me_index", "1");
        // 不获取返回的 _source 的上下文
        getRequest.fetchSourceContext(new FetchSourceContext(false));
        getRequest.storedFields("_none_");

        boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    // 获取文档的信息
    @Test
    void testGetDocument() throws IOException {
        GetRequest getRequest = new GetRequest("me_index", "1");
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(getResponse.getSourceAsString()); // 打印文档的内容
        System.out.println(getResponse); // 返回的全部内容和命令是一样的
    }

    // 更新文档的信息
    @Test
    void testUpdateRequest() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("me_index", "1");
        updateRequest.timeout("1s");

        User user = new User("狂神说Java", 18);
        updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);

        UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(updateResponse.status());
    }

    // 删除文档记录
    @Test
    void testDeleteRequest() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest("me_index", "1");
        deleteRequest.timeout("1s");

        DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(deleteResponse.status());
    }

    // 批量插入数据!
    @Test
    void testBulkRequest() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10s");

        ArrayList<User> userList = new ArrayList<>();
        userList.add(new User("me1", 1));
        userList.add(new User("me2", 1));
        userList.add(new User("me3", 1));
        userList.add(new User("kuangshen1", 3));
        userList.add(new User("kuangshen2", 3));
        userList.add(new User("kuangshen3", 3));

        // 批处理请求
        for (int i = 0; i < userList.size(); i++) {
            // 批量更新和批量删除,就在这里修改对应的请求就可以了
            bulkRequest.add(new IndexRequest("me_index")
                    .id("" + (i + 1))
                    .source(JSON.toJSONString(userList.get(i)), XContentType.JSON));
        }

        BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulkResponse.hasFailures()); // 是否失败,返回 false 代表成功!
    }

    // 查询
    // SearchRequest 搜索请求
    // SearchSourceBuilder 条件构造
    // HighlightBuilder 构建高亮
    // TermQueryBuilder 精确查询
    // MatchAllQueryBuilder
    @Test
    void testSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("me_index");
        // 构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 查询条件,我们可以使用 QueryBuilders 工具来实现
        // QueryBuilders.termQuery 精确
        // QueryBuilders.matchAllQuery  匹配所有
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("naem", "me1");
        //MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(searchResponse.getHits()));
        System.out.println("=================");
        for (SearchHit documentFields : searchResponse.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
    }

实战

确保ElasticSearch保持开启状态

最终效果

在这里插入图片描述

创建一个新的项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

爬虫

数据问题?数据库获取,消息队列中获取,都可以成为数据源,爬虫!

爬取数据:(获取请求返回的页面信息,筛选出我们想要的数据就可以了!)

jsoup包

<!--jSoup解析网页-->
<!--解析网页jsoup-->
<dependency>
       <groupId>org.jsoup</groupId>
       <artifactId>jsoup</artifactId>
       <version>1.14.3</version> 
</dependency>
// 获取请求 https://search.jd.com/Search?keyword=java
        // 前提,需要联网!

        String url = "https://search.jd.com/Search?keyword=java";
        // 解析网页。(Jsoup返回DOcument就是浏览器Document对象)
        Document document = Jsoup.parse(new URL(url), 30000);
        // 所有你在js中可以使用的方法,这里都能使用!
        Element element = document.getElementById("J_goodsList");

        // 获取所有的lj元素
        Elements elements = element.getElementsByTag("li");
        // 获取元素中的内容,这里el就是每一个li标签了!
        for (Element el : elements) {
            // 关于这种图片特别多的网站,所有图片都是延迟加载的!
            // data-lazy-img
            String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
            String price = el.getElementsByClass("p-price").eq(0).text();
            String title = el.getElementsByClass("p-name").eq(0).text();

            System.out.println("===================");
            System.out.println(img);
            System.out.println(price);
            System.out.println(title);
        }

前后端分离

搜索高亮

完成后端效果

在这里插入图片描述

pojo类代码

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content {
    private String title;
    private String img;
    private String price;
    // 可以自己添加属性!
}

代码

工具类代码

@Component
public class HtmlParseUtil {
    public static void main(String[] args) throws IOException {
        new HtmlParseUtil().parseJD("心理学").forEach(System.out::println);
    }

    public List<Content> parseJD(String keywords) throws IOException {
        String url = "https://search.jd.com/Search?keyword=" + keywords;
        Document document = Jsoup.parse(new URL(url), 30000);
        Element element = document.getElementById("J_goodsList");
        Elements elements = element.getElementsByTag("li");

        ArrayList<Content> goodsList = new ArrayList<>();

        // 获取元素中的内容,这里el就是每一个li标签了!
        for (Element el : elements) {
            // 关于这种图片特别多的网站,所有图片都是延迟加载的!
            // data-lazy-img
            String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
            String price = el.getElementsByClass("p-price").eq(0).text();
            String title = el.getElementsByClass("p-name").eq(0).text();
            Content content = new Content();
            content.setTitle(title);
            content.setImg(img);
            content.setPrice(price);
            goodsList.add(content);
        }
        return goodsList;
    }
}

业务层代码

// 业务编写
@Service
public class ContentService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    // 1、解析数据放入 ElasticSearch 索引中
    public Boolean parseContent(String keyWord) throws IOException {
        List<Content> contents = new HtmlParseUtil().parseJD(keyWord);
        // 把查询到的数据放入ElasticSearch中
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");

        for (int i = 0; i < contents.size(); i++) {
            bulkRequest.add(
                    new IndexRequest("jd_goods")
                            .source(JSON.toJSONString(contents.get(i)), XContentType.JSON));
        }

        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return !bulk.hasFailures();
    }

    // 2、获取这些数据实现搜索功能
    public List<Map<String,Object>> searchPageHighlightBuilder(String keyWord,int pageNo,int pageSize) throws IOException {
        if (pageNo <= 1){
            pageNo = 1;
        }

        // 条件搜索
        SearchRequest searchRequest = new SearchRequest("jd_goods");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 分页
        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);

        //精确匹配
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", keyWord);
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        // 执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 解析结果
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit documentFields : response.getHits().getHits()) {
                list.add(documentFields.getSourceAsMap());
        }
        return list;
    }

    // 3、获取这些数据实现高亮功能
    public List<Map<String,Object>> searchPage(String keyWord,int pageNo,int pageSize) throws IOException {
        if (pageNo <= 1){
            pageNo = 1;
        }

        // 条件搜索
        SearchRequest searchRequest = new SearchRequest("jd_goods");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 分页
        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);

        //精确匹配
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", keyWord);
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.requireFieldMatch(false); // 多个高亮显示
        highlightBuilder.preTags("<span style='color: red;'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);

        // 执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 解析结果
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {

            // 解析高亮的字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField title = highlightFields.get("title");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if (title != null){
                Text[] fragments = title.fragments();
                String n_title = "";
                for (Text text : fragments) {
                    n_title += text;
                }
                sourceAsMap.put("title",n_title);
            }
            list.add(sourceAsMap);
        }
        return list;
    }
}

控制层代码

// 请求编写
@RestController
public class ContentController {

    @Autowired
    private ContentService contentService;

    @GetMapping("/parse/{keyword}")
    public Boolean parse(@PathVariable("keyword") String keyWord) throws IOException {
        return contentService.parseContent(keyWord);
    }

    @GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
    public List<Map<String,Object>> search(@PathVariable("keyword") String keyWord,
                                           @PathVariable("pageNo") int pageNo,
                                           @PathVariable("pageSize") int pageSize) throws IOException {
       return contentService.searchPage(keyWord,pageNo,pageSize);
    }

}

原视频地址:https://www.bilibili.com/video/BV17a4y1x7zq?spm_id_from=333.999.0.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是鱼染哟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值