ElasticSearch
安装elasticsearch 官网:elastic.co
https://www.elastic.co/cn/downloads/elasticsearch
官网下载巨慢,下载
目录
文章图片
启动,访问9200:
文章图片
访问9200接口:
文章图片
安装elasticsearch-head: git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start
open http://localhost:9100/
存在一个9200和9100的跨域问题!
点击链接,报跨域的错!
文章图片
修改elasticsearch中config下的yaml配置文件,修改:
文章图片
重启,连接成功:
文章图片
把索引当做一个数据库!可以建立索引(库),文档(库中的数据!)
文章图片
后面所有的查询,查询功能在Kibana中做!
了解ELK
文章图片
安装Kibana
文章图片
好处:ELK基本上都是拆箱即用
启动测试:点bin下的kibana
文章图片
默认的kibana端口为5601
PS:注意elasticsearch和kibana的版本必须一致 否则出错!
开发工具:(Post curl head 谷歌浏览器插件测试)
汉化,修改kibana yaml中配置 重启,
ES核心概念
- 索引
- 字段类型(mapping)
- 文档(documents)
集群、节点、索引、类型、文档、分片、映射是什么?
elasticsearch是面向文档,关系型数据库和elasticsearch 客观的对比如下,一切都是JSON!
文章图片
文章图片
类型示例:
文章图片
【Java|ElasticSearch 7.8.1教程(from b站狂神)+JD商城仿站】
文章图片
文章图片
IK分词器
文章图片
安装https://github.com/medcl/elasticsearch-analysis-ik/releases
放在elasticsearch的plugin(插件)下
重启观察ES
文章图片
关于elasticsearch中的命令 如elasticsearch-plugin:
命令行输入:
elasticsearch-plugin list
在kibana中测分词器:
文章图片
我们输入 超级喜欢狂神或java
发现问题:狂神说被拆开了!
这种自己需要的词,需要自己加到我们的分词器字典中!
向ik分词器增加自己的配置
文章图片
文章图片
重启es、kibana
文章图片
再次测试一下狂神说,看下效果!ik_max_word最细粒度划分
文章图片
文章图片
以后自定义dic、导入即可!
索引引擎里面最重要的首先就是分词
Rest风格说明 一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制!
文章图片
基础测试
- 创建一个索引!也是在kibana终端中试用版PUT命令
PUT /test1/type1/1{
"name": "狂神说",
"age": "3"
}
文章图片
完成了自动增加索引!数据也成功的添加了,这就是可以当做数据库看的原因。。
- 那么name字段用不用指定类型呢?毕竟我们关系型数据库 是需要指定类型的啊!
- 字符串类型 text、keyword
- 数值类型 long、integer、short、byte、double、float、scaled float
- 日期类型date
- te布尔值类型boolean
- 二进制类型binary
- 等等。。。
- 指定字段的类型——创建规则
文章图片
文章图片
GET命令得到库的信息:
文章图片
文章图片
- 查看默认的信息
文章图片
文章图片
修改 提交还是使用PUT即可!然后覆盖!最新办法
曾经的办法:
文章图片
现在的方法 使用POST:
文章图片
删除索引——DELETE
文章图片
通过DELETE命令实现删除、根据你的请求来判断是删除索引还是删除文档记录!
使用RESTFUL风格是我们ES推荐大家使用的!
关于文档的基本操作(重点): 基本操作:
添加数据
文章图片
文章图片
更新数据,将小明改成小红
文章图片
PUT更新数据
文章图片
version代表被改变的次数
Post,_update自由度更高,PUT必须一次性修改一个个体的全部内容,但是Post可以选择部分修改!
文章图片
这个和PUT无异,要在后加_update
文章图片
文章图片
简单的搜索:
GET Kuangshen/user/_search?q=name:狂神说
文章图片
简单的条件查询,可以根据默认的映射规则,产生基本的查询!
文章图片
复杂操作搜索 select(排序,分页,高亮,模糊查询,精准查询)
GET kuangshen/_search
输出:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "kuangshen",
"_type" : "user",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "狂神说",
"age" : 23,
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"温暖",
"直男"
]
}
},
{
"_index" : "kuangshen",
"_type" : "user",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 3,
"desc" : "法外狂徒",
"tags" : [
"交友",
"旅游",
"渣男"
]
}
},
{
"_index" : "kuangshen",
"_type" : "user",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"name" : "李四",
"age" : 30,
"desc" : "不知道如何形容",
"tags" : [
"篮球",
"IT",
"型男"
]
}
},
{
"_index" : "kuangshen",
"_type" : "user",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"name" : "王五",
"age" : 32,
"desc" : "就是一个屌丝",
"tags" : [
"羽毛球",
"钢琴",
"渣男"
]
}
},
{
"_index" : "kuangshen",
"_type" : "user",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"name" : "狂神说Java8",
"age" : 34,
"desc" : "就是一个大帅哥",
"tags" : [
"围棋",
"小提琴",
"暖男"
]
}
}
]
}
}
GET kuangshen/_search
{
"query": {
"match": {
"name": "狂神"
}
}
}
输出:
{
"took" : 9,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.9034984,
"hits" : [
{
"_index" : "kuangshen",
"_type" : "user",
"_id" : "1",
"_score" : 1.9034984,
"_source" : {
"name" : "狂神说",
"age" : 23,
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"温暖",
"直男"
]
}
},
{
"_index" : "kuangshen",
"_type" : "user",
"_id" : "5",
"_score" : 1.6534033,
"_source" : {
"name" : "狂神说Java8",
"age" : 34,
"desc" : "就是一个大帅哥",
"tags" : [
"围棋",
"小提琴",
"暖男"
]
}
}
]
}
}
hit: 索引和文档信息
查询的结果总数
然后就是查询出来的具体文档
数据中的东西都可以遍历出来
分数:通过score判断谁更加符合结果
指定字段查询:
GET kuangshen/_search
{
"query": {
"match": {
"name": "狂神"
}
},
"_source": ["name","desc"]
}
之后使用java操作es,所有的方法和对象就是这里面的key!
复杂操作:
排序 order中的desc降序、asc升序; 按照age
GET kuangshen/_search
{
"query": {
"match": {
"name": "狂神"
}
}
,"sort": [
{
"age": {
"order": "desc"
}
}
]
}
分页
GET kuangshen/_search
{
"query": {
"match": {
"name": "狂神"
}
}
,"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 1
}
From:从第几个数据开始,返回多少条数据(单页面的数据)
数据下标还是从0开始的,和学的所有数据结构是一样的
/search/{current}/{pagesize}
布尔值查询 通过布尔值进行更加精确的查询:多条件精确查询
must命令(相当于mysql的and),即所有条件要同时符合;如果将must改为should(相当于or),则只要满足其一即可;
类似的 must not 查询不是。。
GET kuangshen/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "狂神说"
}
},
{
"match": {
"age": 23
}
}
]
}
}
}
过滤器(filter) 筛选age范围
GET kuangshen/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "狂神"
}
}
],
"filter": [
{
"range": {
"age": {
"gte": 10,
"lte": 40
}
}
}
]
}
}
}
- gt 大于
- gte 大于等于
- lt 小于
- lte 小于等于
GET kuangshen/user/_search
{
"query": {
"match": {
"tags": "男 技术"
}
}
}
文章图片
多个条件使用空格隔开
只要满足其中一个结果即可以被查出
这个时候可以通过分值基本的判断
精确查询 term查询是直接通过待排索引指定的词条进行精确的查找的!
关于分词:
term,直接查询精确的
match:会使用分词器解析!(先分析文档,然后再通过分析的文档进行查询!)
两个字段类型text keyword
#新建db
PUT testdb
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"desc":{
"type": "keyword"
}
}
}
}
#插入两条数据
PUT testdb/_doc/1
{
"name": "狂神说Java name",
"desc": "狂神说Java name"
}
PUT testdb/_doc/2
{
"name": "狂神说Java name",
"desc": "狂神说Java name2"
}
文章图片
GET _analyze
{
"analyzer": "keyword",
"text": "狂神说Java name"
}
GET _analyze
{
"analyzer": "standard",
"text": "狂神说Java name"
}
文章图片
文章图片
由于desc的type是keyword,当做整体去搜索了
总结:keyword字段类型不会被分词器解析!
多个值匹配的精确查询 精确查询多个值
文章图片
高亮查询
GET kuangshen/user/_search
{
"query": {
"match": {
"name": "狂神说"
}
},
"highlight": {
"pre_tags": "",
"post_tags": "
",
"fields": {
"name": {}
}
}
}
默认是
标签文章图片
也可以是自定义标签:设置pre_tags、post_tags
文章图片
- 匹配
- 按照条件匹配
- 精确匹配
- 区间范围匹配
- 匹配字段过滤
- 多条件查询
- 高亮查询
https://www.elastic.co/guide/index.html
文章图片
找原生依赖
文章图片
初始化
文章图片
配置 新建一个empty project ,再创建普通模块
文章图片
创建Springboot 模块:
文章图片
勾上依赖:
文章图片
由于刚刚建的空project,故要陪JDK环境
文章图片
文章图片
文章图片
文章图片
问题:一定要保证我们的导入依赖和我们的es版本一致
默认的导入依赖和我们本地的版本不一致!
可以自定义版本依赖,保证一致
新建config、ElasticSearchConfig.java`
package com.kuang.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//狂神的spring两步骤:
//1.找对象
//2.放到spring中用
@Configuration
public class ElasticSearchConfig {//
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
return client;
}
}
源码
文章图片
具体测试es api:
package com.kuang;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
//es 高级客户端测试API
@SpringBootTest
class KuangshenEsApiApplicationTests {
//面向对象来操作
@Autowired
@Qualifier("restHighLevelClient")//这里的qualifier用来指定下面的client为原始的restHighLevelClient
private RestHighLevelClient client;
// 测试索引的创建 Request
@Test
void testCreateIndex() throws IOException {
// 1.创建索引请求 相当于kibana中的PUT
CreateIndexRequest request = new CreateIndexRequest("kuang_index");
// 2.执行创建请求IndicesClient ,请求后获得响应
CreateIndexResponse createIndexResponse =
client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}//测试获取索引判断是否存在某索引
@Test
void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("kuang_index");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
} // 测试删除索引
@Test
void testDeleteIndex()throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("testdb2");
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
}
本来应该是private RestHighLevelClient restHighLevelClient; 这里为了简便,所以用Qualifier来限定client为restHighLevelClient;
文章图片
文章图片
文章图片
- 创建索引
- 判断索引是否存在
- 删除索引
- 创建文档
- crud文档
package com.kuang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
private String name;
private int age;
}
由于要将我们的数据放入请求 json,故在pom中导入阿里巴巴fastjson
这里是将对象编写为Json,再放入es的request中
编写test类:
@Test
void testAddDocument(){
//创建对象
User user = new User("狂神说",3);
IndexRequest request = new IndexRequest("kuang_index");
// 规则 put /kuang_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");
//将我们的数据放入请求 json
request.source(JSON.toJSONString(user), XContentType.JSON);
//客户端发送请求
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
//
System.out.println(indexResponse.status());
//对应我们命令返回的状态
}
文章图片
获取文档
//获取文档的信息
@Test
void testGetDocument() throws IOException {
GetRequest getRequest = new GetRequest("kuang_index", "1");
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(getResponse.getSourceAsString());
//打印文档的内容
System.out.println(getResponse);
//返回的全部内容和命令是一样的
}
文章图片
更新文档信息
//更新文档的信息
@Test
void testUpdateDocument() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("kuang_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 request = new DeleteRequest("kuang_index", "1");
request.timeout("1s");
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
System.out.println(deleteResponse.status());
}
批量插入
//批量插入数据
@Test
void testBulkRequest() throws IOException{
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
//数据量大的时候,秒数可以增加ArrayList userList = new ArrayList<>();
userList.add(new User("psz",11));
userList.add(new User("psz2",12));
userList.add(new User("psz3",13));
userList.add(new User("psz4",14));
userList.add(new User("psz5",15));
//批处理请求
for (int i = 0;
i < userList.size();
i++) {
bulkRequest.add(
new IndexRequest("kuang_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:成功
}
文章图片
查询 小技巧:
一般企业中,会把index名存在utils里面的ESconst.java文件中:
package com.kuang.utils;
public class ESconst {
public static final String ES_INDEX = "kuang_index";
}
// 查询
// SearchRequest 搜索请求
// SearchSourceBuilder 条件构造
// HighlightBuilder 构建高亮
// TermQueryBuilder 精确查询
// MatchAllQueryBuilder
// xxx QueryBuilder 对应我们刚才看到的命令 @Test
void testSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest(ESconst.ES_INDEX);
// 构建搜索的条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 查询条件,可以使用querybuilders工具类实现
// QueryBuilders.termQuery精确匹配
// QueryBuilders.matchAllQuery匹配所有
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "qinjiang1");
//MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
sourceBuilder.query(termQueryBuilder);
//分页
//sourceBuilder.from();
//sourceBuilder.size();
// 设置查询的时间 希望在60s内查出
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());
}
}
JD商城实战 新建Springboot initializr项目
导入es、fastjson等pom下的依赖
爬虫
数据问题?数据库获取,消息队列中获取,都可以成为数据源,或者爬虫
爬取数据:(获取请求返回的页面信息,筛选出我们想要的数据就可以了)
jsoup包:用于解析网页,不能爬电影
新建一个utils包放网页解析的工具类
文章图片
本质的请求是:
https://search.jd.com/Search?keyword=java
文章图片
所有在Js中的方法这里都可以使用
package com.kun.utils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
public class HtmlParseUtil {
public static void main(String[] args) throws IOException {
// 获取请求 https://search.jd.com/Search?keyword=java
String url = "https://search.jd.com/Search?keyword=java";
//解析网页 Jsoup返回的就是浏览器Document对象
Document document = Jsoup.parse(new URL(url), 30000);
Element element = document.getElementById("J_goodsList");
System.out.println(element.html());
//获取所有的li元素/标签
Elements elements = element.getElementsByTag("li");
//获取元素中的内容eq获取当前第一个元素,获取src属性
for (Element el : elements) {
//关于这种图片特别多的网站,所有的图片都是延迟加载的!
String img = el.getElementsByTag("img").eq(0).attr("src");
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,Content.java
package com.kun.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Content {
private String title;
private String img;
private String price;
//可以自己添加属性
}
再次封装工具类:
package com.kun.utils;
import com.kun.pojo.Content;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
@Component //丢进Springboot中
public class HtmlParseUtil {
public static void main(String[] args) throws Exception {
new HtmlParseUtil().parseJD("java").forEach(System.out::println);
}public List parseJD(String keywords) throws Exception {
// 获取请求 https://search.jd.com/Search?keyword=java
String url = "https://search.jd.com/Search?keyword=" + keywords;
//解析网页 Jsoup返回的就是浏览器Document对象
Document document = Jsoup.parse(new URL(url), 30000);
//所有你在js中可以使用的方法,这里都可以使用
Element element = document.getElementById("J_goodsList");
//System.out.println(element.html());
//获取所有的li元素/标签
Elements elements = element.getElementsByTag("li");
//封装对象
ArrayList goodsList = new ArrayList();
//获取元素中的内容eq获取当前第一个元素,获取src属性
for (Element el : elements) {
//关于这种图片特别多的网站,所有的图片都是延迟加载的!
String img = el.getElementsByTag("img").eq(0).attr("src");
String price = el.getElementsByClass("p-price").eq(0).text();
String title = el.getElementsByClass("p-name").eq(0).text();
Content content = new Content();
content.setImg(img);
content.setPrice(price);
content.setTitle(title);
goodsList.add(content);
//System.out.println("===============================");
//System.out.println(img);
//System.out.println(price);
//System.out.println(title);
}
return goodsList;
}
}
编写业务层service:
package com.kun.service;
import com.alibaba.fastjson.JSON;
import com.kun.pojo.Content;
import com.kun.utils.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.context.annotation.Bean;
import org.springframework.stereotype.Service;
import java.util.List;
//业务编写
@Service
public class ContentService {
@Autowired
private RestHighLevelClient restHighLevelClient;
//1.解析数据放入es索引中
public Boolean parseContent(String keywords) throws Exception {
List contents = new HtmlParseUtil().parseJD(keywords);
//把查询的数据放入我们的es中
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();
}
}
测试:由于这个文件中又Autowire,所以就算建了主函数psvm,也不能测,必须启动服务;
直接用controller来测:
package com.kun.controller;
import com.kun.service.ContentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ContentController {
@Autowired
private ContentService contentService;
@GetMapping("/parse/{keyword}")
public Boolean parse(@PathVariable("keyword") String keywords) throws Exception {
returncontentService.parseContent(keywords);
}
}
再在业务层中实现搜索功能:
// 2. 获取数据实现搜索功能
public List
用Controller来测:
@GetMapping("/parse/{keyword}/{pageNo}/{pageSize}")
public List> search(@PathVariable("keyword") String keyword,
@PathVariable("pageNo")int pageNo,
@PathVariable("pageSize") int pageSize) throws IOException {
return contentService.searchPage(keyword, pageNo, pageSize);
}
前后端分离
先在一个任意包下
npm install vue
生成vue文件,将内部一些js包导入Springboot项目中;axios.min.js;
vue.min.js文章图片
文章图片
在前端每个商品中得到result值
文章图片
搜索高亮
修改业务层ContentService.java
//3. 新增高亮功能
public List> searchPageHighlightBuilder(String keyword,int pageNo,int pageSize) throws Exception {
parseContent(keyword);
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));
//match匹配 可以支持中文搜索
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", keyword);
sourceBuilder.query(matchQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//超时
//高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
//高亮的字段
highlightBuilder.requireFieldMatch(false);
//如果一句里面有多个关键词高亮,则只显示第一个
highlightBuilder.preTags("");
highlightBuilder.postTags("");
sourceBuilder.highlighter(highlightBuilder);
//执行搜索
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList> list = new ArrayList<>();
for (SearchHit hit : searchResponse.getHits().getHits()) {Map, HighlightField> highlightFields = hit.getHighlightFields();
//获取到高亮字段
HighlightField title = highlightFields.get("title");
Map, 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;
}
效果
推荐阅读
- java|JAVA计算机毕业设计大学生网络创业就业管理系统Mybatis+源码+数据库+lw文档+系统+调试部署
- Nebula|开源图编辑库 NebulaGraph VEditor 的设计思路分享
- 芯片|进阶研学大咖说04期 |包云岗《开源芯片的机遇与挑战》
- java|阿里MaxCompute生态团队负责人—李睿博 : 参与开源,让自己的履历与众不同|《大神详解开源 BUFF 增益攻略》讲座回顾...
- Android|Android AOSP资源的下载
- Android|ubuntu16.04 编译Android AOSP源码 android10
- 项目|SpringBoot调用腾讯云短信服务
- java开发|SpringBoot 整合 Redis 短信验证码登录
- java|SpringBoot整合腾讯云短信服务实现发送短信功能(一篇就够了)