ElasticSearch7.6

ElasticSearch7.6

elasticsearch:

安装:
     1 解压,
     2 bin
     3 启动
目录:
     bin 启动文件
     config 配置文件
         log4j2 日志配置文件
         jvm.options java 虚拟机相关的配置
         elasticsearch.yml elasticsearch 的配置文件! 默认 9200 端口! 跨域!
         lib 相关jar包
         logs 日志!
         modules 功能模块
         plugins 插件!

安装可视化插件:

安装:
          1 elasticsearch-head-master,解压
          2 npm install npm run start , 需要node环境
          3 解决跨域问题,elasticsearch->config->elasticsearch.yml配置:
             http.cors.enabled: true
             http.cors.allow-origin: "*"

Kibana:

 1、解压后端的目录
 2、启动
 3、访问测试
 4、开发工具! (Post、curl、head、谷歌浏览器插件测试!)
 5、汉化,i18n.locale: "zh-CN"

ES核心概念
在这里插入图片描述

在这里插入图片描述

IK分词器插件

安装:
	1、https://github.com/medcl/elasticsearch-analysis-ik
	2、下载完毕之后,放入到我们的elasticsearch 插件,plugins目录
	3、重启观察ES,可以看到ik分词器被加载了!
	4、elasticsearch-plugin 可以通过这个命令来查看加载进来的插件
	5、使用kibana测试!
其他:
	ik_smart 和 ik_max_word,其中 ik_smart 为最少切分,ik_max_word为最细 粒度划分!
	config/IKAnalyzer.cfg.xml  添加加载分词规则,main.dic默认加载 (必定添加main)
methodurl地址描述
PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)
POSTlocalhost:9200/索引名称/类型名称创建文档(随机文档id)
_updatellocalhost:9200/索引名称/类型名称/文档id/_update修改文档
DELETElocalhost:9200/索引名称/类型名称/文档id删除文档
GETlocalhost:9200/索引名称/类型名称/文档id查询文档通过文档id
POSTlocalhost:9200/索引名称/类型名称/_search查询所有数据

api操作

添加

PUT /zgc/user/2
{
"name": "狂神说java",
"age" : 10,
"desc": "还行",
"tags": ["技术宅","帅哥","渣男"]
}

PUT更新

空的字段会覆盖,不推荐

PUT /zgc/user/1
{
"name": "狂神说123",
"desc": "一顿操作猛如虎,一看工资2500",
"tags": ["技术宅","温暖","直男"]
}

POST更新

灵活,推荐

POST /zgc/user/1/_update
{
  "doc":{
    "name": "狂神说222222"
  }
}

简单查询

GET /zgc/user/1

1,分词并且搜索词拆分

// 查询文档1,2
POST /zgc/user/_search?q=name:狂神说java

2,分词并且搜索词拆分

GET /zgc/user/_search
{
  "query": {
    "match": {
      "name": "狂神说"
    }
  }
}

_source指定字段,sort排序,

GET /zgc/user/_search
{
  "query": {
    "match": {
      "name": "狂神说"
    }
  }
  , "_source": ["name","tags","age"]
  ,"sort": [
    {
      "age": {
        "order": "asc"
      }
    }
  ]
  ,"from": 0
  ,"size": 2
}

most (and),should (or),must_not (not)

GET /zgc/user/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "name": "java"
          }
        },
        {
          "match": {
            "age": "10"
          }
        }
      ]
    }
  }
}

匹配多个值 or并且搜索词拆分

GET /zgc/user/_search
{
  "query": {
    "match": {
      "tags": "男  帅哥"
    }
  }
}

term 不能把搜索词拆分

GET /zgc/user/_search
{
  "query": {
    "term": {
      "name": "狂"
    }
  }
}

filter,过滤器

# query->bool->filter
# filter比query快的原因:
# 1 query:会先比较查询条件,然后计算分值,最后返回文档结果;filter: 1 对结果进行缓存 2 避免计算分值
GET /zgc/user/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "age": {
            "gte": 10,
            "lte": 200
          }
        }
      }
    }
    
  }
}

高亮查询

GET /zgc/user/_search
{
  "query": {
    "match": {
      "name": "狂神"
    }
  }
  ,"highlight": {
    "fields": {
      "name":{}
    }
  }
}

自定义高亮查询

GET /zgc/user/_search
{
  "query": {
    "match": {
      "name": "狂神"
    }
  }
  ,"highlight": {
    "fields": {
      "name":{}
    }
    ,"pre_tags": "<p class='key' style='color:red' >"
    ,"post_tags": "</p>"
  }
}

集成SpringBoot

https://www.elastic.co/guide/en/elasticsearch/client/index.html
在这里插入图片描述
在这里插入图片描述

maven

<elasticsearch.version>7.6.1</elasticsearch.version>

springboot配置

// 新建ElasticSearchClientConfig文件
@Configuration
public class ElasticSearchClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient() {

        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")
                )
        );
        return client;
    }
}

包,搜autoconfigure->搜elasticearch->ElasticsearchRestClientAutoConfiguration

@Import({RestClientBuilderConfiguration.class, RestHighLevelClientConfiguration.class, RestClientFallbackConfiguration.class})

索引操作

@Autowired
private RestHighLevelClient restHighLevelClient;

// 创建索引
@Test
void createIndex() throws IOException {
	CreateIndexRequest createIndexRequest = new CreateIndexRequest("zgc_index");
	CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
	System.out.println(createIndexResponse);
}
//org.elasticsearch.client.indices.CreateIndexResponse@998a69c8

// 判断索引是否存在
@Test
void existIndex() throws IOException {
	GetIndexRequest getIndexRequest = new GetIndexRequest("zgc_index");
	boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
	System.out.println(exists);
}
//true

// 删除索引
@Test
void delIndex() throws IOException {
	DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("zgc_index");
	AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
	System.out.println(delete);
	System.out.println(delete.isAcknowledged());
}
//org.elasticsearch.action.support.master.AcknowledgedResponse@4ee
//true

文档操作

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}
// 添加文档(行) put /zgc_index/_doc/1  {xxx}
@Test
void addDocument() throws IOException {
    User user = new User("陈小周2", 18);
    String string = JSON.toJSONString(user);

    IndexRequest indexRequest = new IndexRequest("zgc_index");
    indexRequest.source(string, XContentType.JSON);
    indexRequest.timeout(TimeValue.timeValueSeconds(1));
    indexRequest.id("2"); // 手动指定id

    IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    System.out.println(index.toString());
    System.out.println(index.status());
}
//IndexResponse[index=zgc_index,type=_doc,id=2,version=1,result=created,seqNo=3,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
//CREATED

// 判断文档是否存在(和判断索引差不多)
@SneakyThrows
@Test
void existDocument() throws IOException {
    GetRequest getRequest = new GetRequest("zgc_index", "2");

    boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
    System.out.println(exists);
}
//true


// 获取文档
@Test
void getDocument() throws IOException {
    GetRequest getRequest = new GetRequest("zgc_index", "1");

    GetResponse documentFields = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
    System.out.println(documentFields);
    System.out.println(documentFields.getSourceAsString());
}
//{"_index":"zgc_index","_type":"_doc","_id":"1","_version":3,"_seq_no":2,"_primary_term":1,"found":true,"_source":{"age":18,"name":"陈小周"}}
//{"age":18,"name":"陈小周"}

// 更新文档
@Test
void updateDucement() throws IOException {
    UpdateRequest updateRequest = new UpdateRequest("zgc_index", "1");
    User user = new User("陈大周", 99);
    updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
	updateRequest.timeout("1s");

    UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
    System.out.println(update);
    System.out.println(update.status());
}
//UpdateResponse[index=zgc_index,type=_doc,id=1,version=4,seqNo=4,primaryTerm=1,result=updated,shards=ShardInfo{total=2, successful=1, failures=[]}]
//OK

// 删除文档
@Test
void delDocument() throws IOException {
	DeleteRequest deleteRequest = new DeleteRequest("zgc_index","2");
	deleteRequest.timeout("1s");
	DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
	System.out.println(delete);
	System.out.println(delete.status());
}
//DeleteResponse[index=zgc_index,type=_doc,id=2,version=2,result=deleted,shards=ShardInfo{total=2, successful=1, failures=[]}]
//OK

批量插入

// 批量插入
@Test
void bulkDocument() throws IOException {
    ArrayList<User> users = new ArrayList<>();
    users.add(new User("aa", 10));
    users.add(new User("bb", 11));
    users.add(new User("cc", 12));
    BulkRequest bulkRequest = new BulkRequest();
    bulkRequest.timeout("10s");
    for (int i = 0; i < users.size(); i++) {
        bulkRequest.add(new IndexRequest("zgc_index").id("" + (i + 1)).source(JSON.toJSONString(users.get(i)),XContentType.JSON));
    }

    BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    System.out.println(bulk);
    System.out.println(bulk.status());
    System.out.println(bulk.hasFailures()); // 返回false代表成功
}
//org.elasticsearch.action.bulk.BulkResponse@1f39269d
//OK
//false

查询

    // 查询
    @Test
    void search() throws IOException {
        // 查询请求
        SearchRequest searchRequest = new SearchRequest("zgc_index");
        // 查询构造
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 查询条件 1和2
//		TermQueryBuilder  termQueryBuilder =  QueryBuilders.termQuery("name","aa");
        QueryBuilder termQueryBuilder = new TermQueryBuilder("name", "aa");
//		searchSourceBuilder.highlighter();
        searchSourceBuilder.query(termQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(search);

        System.out.println(JSON.toJSONString(search.getHits()));
        System.out.println("----------------------------------");
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        System.out.println("===========================================");
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }
    //{"took":12,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":0.9808291,"hits":[{"_index":"zgc_index","_type":"_doc","_id":"1","_score":0.9808291,"_source":{"age":10,"name":"aa"}}]}}
    //{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{"$ref":"$.hits[0].fields"},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.9808291,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"aa","age":10},"sourceAsString":"{\"age\":10,\"name\":\"aa\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":0.9808291,"totalHits":{"relation":"EQUAL_TO","value":1}}
    //----------------------------------
    //{name=aa, age=10}
    //===========================================
    //{name=aa, age=10}

京东搜索实战

访问静态页面

在这里插入图片描述
注意:上文修改ElasticSearch版本包的添加config包和其文件,导入静态资源

server.port=9090
# 关闭thymeleaf的缓存
spring.thymeleaf.cache=false
@Controller
public class Jd {
    @GetMapping({"/", "/jd"})
//    @ResponseBody
    public String jd() {
        return "index";
    }
}
// 可以访问首页

数据爬取

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.2</version>
</dependency>
package com.zgc.esjd3.util;

import com.zgc.esjd3.pojo.Content;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

@Component
public class HtmlParseUtil {
//    public static void main(String[] args) throws IOException {
//        HtmlParseUtil htmlParseUtil = new HtmlParseUtil();
//        htmlParseUtil.parseJd("java");
//    }
    public ArrayList<Content> parseJd(String keyword) throws IOException {
        // url
        String url = "https://search.jd.com/Search?keyword=" + keyword;
        // 解析网页,返回Document
        Document parse = Jsoup.parse(new URL(url), 3000);
        Element j_goodsList = parse.getElementById("J_goodsList");
        Elements elements = j_goodsList.getElementsByTag("li");
        ArrayList<Content> contentArrayList = new ArrayList<>();

        for (Element element : elements) {
            String img = element.getElementsByTag("img").eq(0).attr("src");
            String price = element.getElementsByClass("p-price").eq(0).text();
            String title = element.getElementsByClass("p-name").eq(0).text();
            if (title.length() != 0 && img != null) {
                Content content = new Content(title, img, price);
                contentArrayList.add(content);
            }
        }
        System.out.println(contentArrayList);
        return contentArrayList;
    }
}

数据存进es

package com.zgc.esjd3.service;

import com.alibaba.fastjson.JSON;
import com.zgc.esjd3.pojo.Content;
import com.zgc.esjd3.util.HtmlParseUtil;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;

@Service
public class ContentService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    // Jsoup数据放es
    public boolean parseContent(String keyword) throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("3m");
        ArrayList<Content> contents = new HtmlParseUtil().parseJd(keyword);
        for (int i = 0; i < contents.size(); i++) {
            bulkRequest.add(new IndexRequest("jd_index").id("" + (i + 1)).source(JSON.toJSONString(contents.get(i)), XContentType.JSON));
        }

        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return !bulk.hasFailures();  // hasFailures返回false为成功
    }

}
@GetMapping("/jdTest/{keyword}")
@ResponseBody
public String jdTest(@PathVariable String keyword) throws IOException {
    System.out.println(keyword);
    boolean b = contentService.parseContent(keyword);
    System.out.println(b);
    return keyword;
}
// 访问http://localhost:9090/jdTest/java,成功把数据录入es

实现搜索功能

//分页+搜索+高亮业务编写

public List<Map<String, Object>> searchPage(String keyword, int pageNo, int pageSize) throws IOException {
        if (pageNo <= 1) {
            pageNo = 1;
        }
        // 查询请求
        SearchRequest searchRequest = new SearchRequest("jd_index");
        // 查询构造
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

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

        //精准匹配
        TermQueryBuilder queryBuilder = QueryBuilders.termQuery("title", keyword);
        searchSourceBuilder.query(queryBuilder);

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

        // 执行搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(search);
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit hit : search.getHits()) {
            //解析高亮的字段,将原来的字段换为我们高亮的字段即可
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField title1 = highlightFields.get("title");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果
            //解析高亮的字段,将原来的字段换为我们高亮的字段即可
            if (title1 != null) {
                Text[] fragments = title1.fragments();
                String n_title = "";
                for (Text text : fragments) {
                    n_title += text;
                }
                sourceAsMap.put("title", n_title);
            }
            list.add(sourceAsMap);
        }
        return list;
    }
    @GetMapping({"/", "/jd"})
//    @ResponseBody
    public String jd() {
        return "index";
    }

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

下载 vue:
cnpm install vue
cnpm install axios
把两个文件放入static
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 11
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值