ElasticSearch学习总结(基础篇,可学习,可复习)
推荐:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。。 点击跳转到网站
最近一周都在学习ElasticSearch,之前也零零散散的学过一点,这次下定决心花一周的时间将之前学的知识总结一下,顺便接着再往下学习,所以写篇博客总结一下最近一周的成果,本篇属于ElasticSearch的基础篇,后面会继续深入学习。也希望这篇拙作可以帮助到诸位大佬,如有不足之处,还望诸佬不吝赐教,倾囊相授。
ElasticSearch学习总结
- ElasticSearch概述
- ES和Solr的差别
- ElasticSearch简介
- Solr简介
- ElasticSearch安装
- ES核心概念
- IK分词器
- Rest风格说明
- 关于文档的基本操作(重点)
- 集成SpringBoot
- 实战案例
ElasticSearch概述
ElasticSearch、简称ES,ES是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储,检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别(大数据时代)的数据,ES也使用Java开发使用Lucene作为其核心来实现所有索引和搜索的功能,但是他的目的是通过简单的RestFul API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
ES和Solr的差别
ElasticSearch简介
ElasticSearch是一个实时分布式搜索和分析引擎,它让你以前所未有的速度处理大数据成为可能
它用于全文搜索、结构化、分析以及将这三者混合使用
维基百科使用ElasticSearch提供全文搜索并高亮关键字,以及输入实时搜索(search-asyou-type)和搜索纠错等搜索建议功能……
ElasticSearch是一个基于Apache Lucene的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进,性能最好的,功能最全的搜索引擎库
但是,Lucene只是一个库,想要使用它,你必须使用java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的
ElasticSearch也使用java开发并使用Lucene作为其核心来实现所有索引和搜索功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单!
Solr简介
Solr是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器,Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展、并对索引、搜索性能进行了优化!
Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr索引的实现方法很简单,==用POST方法向Solr服务器发送一个描述Field及其内容的XML文档,Solr根据xml文档添加,删除,更新索引,==Solr搜索只需要发送HTTP GET请求,然后对Solr返回xml、json等格式的查询结果进行解析,组织页面布局,Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。
Solr是基于Lucene开发企业级搜索服务器,实际上就是封装Lucene
Solr是一个独立的企业级搜索应用服务器,它对外提供类似与web-service的API接口,用户可以通过http请求,向搜索引擎服务器提交一定格式的文件,生成索引,也可以通过提交查找请求,并得到返回结果!
ElasticSearch 和 Solr
- 当单纯的对已有数据进行搜索时,Solr更快!
- 当实时建立索引时,Solr会产生IO阻塞,查询性能较差,ElasticSearch具有明显的优势
- 随着数据量的增加,Solr的搜索效率会变得更低,而ElasticSearch却没有明显的的变化
ElasticSearch vs Solr
- ES基本是开箱即用(解压就可以用),非常简单,Solr安装稍微复杂一点
- Solr利用Zookeeper进行分布式管理。而ElasticSearch自身带有分布式协调管理功能
- Solr支持更多格式的数据,比如JSON、XML、CSV,而ElasticSearch仅支持json文件格式
- Solr官方提供的功能更多,而ElasticSearch本身更注重核心功能,高级功能多有第三方插件提供,例如,图形化界面,Kibana友好支撑
- Solr查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用;
- ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索
- Solr是传统搜索应用的有利解决方案,但ElasticSearch更适用于新兴的实时搜索应用
6.Solr比较成熟,有一个更大,更成熟的用户,开发和贡献者社区,而ElasticSearch相对开发维护者少,更新太快,学习成本较高
ElasticSearch安装
Java开发,ElasticSearch的版本和我们之后对应的java的核心jar包,版本对应,java环境正常!
2、熟悉目录
bin 启动文件
config 配置文件log4j2 日志配置文件jvm.options java虚拟机相关的配置ElasticSearch ElasticSearch配置文件 默认端口9200 !跨域lib 相关jar包
modules 功能模块
plugins 插件
3、启动 ,访问9200 elasticsearch.bat
4、访问测试
安装可视化界面 es head的插件
1、下载地址https://github.com/mobz/elasticsearch-head
2、启动
npm install 安装依赖
npm run start 启动
3、连接测试发现,存在跨域问题:配置es
http.cors.enabled: true
http.cors.allow-origin: "*"
4、重启es ,再次连接
初学,可以把es当做一个数据库!(可以建立索引(库),文档(库中的数据))
这个head我们就把它当做数据展示工具!我们后面所有的查询,Kibana
安装Kibana
Kibana是一个针对ElasticSearch的开源分析及可视化平台,用来搜索,查看交互存储在ElasticSearch索引中的数据,使用Kibana,可以通过各种图表进行高级数据分析及展示,Kibana让海量数据更容易理解,基于浏览器的用户界面可以快速创建仪表板实时显示ElasticSearch查询动态,设置Kibana非常简单,无序编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动ElasticSearch索引检测。
官网:https://www.elastic.co/cn/kibana
Kibana版本要和ES版本一致
启动测试
1、目录结构
2、启动
3、开发工具!(POST、curl、head、谷歌浏览器插件)
之后的所有的操作都在这里编写
4、汉化!自己修改Kibana.yml
! zh-CN
ES核心概念
概述
集群、节点、索引、类型、文档、分片、映射是什么?
elasticSearch是面向文档,关系型数据库 和 ElasticSearch 客观的对比!一切都是JSON
Relational DB | ElasticSearch |
---|---|
数据库(database) | 索引(indices) |
表(tables) | types |
行(rows) | documents |
字段(columns) | fields |
elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档重女又包含多个字段(列)
物理设计:
ElasticSearch在后台把每个索引划分为多个分片,每分分片可以在集群中的不同服务器间迁移
逻辑设计:
一个索引类型中,包含多个文档,比如说文档1,文档2,当我们索引一篇文档时,可以通过这样的一个顺序找到它:索引–>类型–>文档ID。通过这个组合我们就能索引到某个具体的文档,注意:ID不必是整数,实际上它是个字符串
文档
之前说ElasticSearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,ElasticSearch,文档有几个重要属性:
- 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含key:value
- 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的
- 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在ElasticSearch中,对于字段是非常灵活的,有时候,我们可以忽略改字段,或者动态的添加一个新的字段
- 尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整型,因为ElasticSearch会保存字段和类型之间的映射及其他的设置,这种映射具体到每个映射的每种类型,这也是为什么在ElasticSearch中,类型有时候也称为映射类型。
类型
索引(就是一个数据库)
倒排索引
IK分词器
什么是IK分词器
分词:即把一段中文或者别的划分成一个个的关键字,我们把搜索时会把自己的信息进行分词,会把数据库中或索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词。比如:“我爱狂神”会被分为:”我“,”爱“,”狂“,”神“,这显然是不符合要求的,所以我们需要安装中文分词器IK来解决这个问题
IK提供了两个分词算法:ik_smart和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度划分
下载安装
1、https://github.com/medcl/elasticsearch-analysis-ik
2、下载完毕之后,直接放在ElasticSearch插件中即可!
3、重启ElasticSearch
测试分词器效果
ik__smart
ik_max_word
ik分词器增加自己的配置!
保存后重启ES!
Rest风格说明
一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件,它主要用于客户端和服务端交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
基本的Rest命令说明:
method | url地址 | 描述 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档id | 创建文档(指定文档id) |
POST | localhost:9200/索引名称/类型名称 | 创建文档(随机文档id) |
POST | localhost:9200/索引名称/类型名称/文档id/_update | 修改文档 |
DELETE | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET | localhost:9200/索引名称/类型名称/文档id | 查询文档通过文档id |
POST | localhost:9200/索引名称/类型名称/_search | 查询所有数据 |
基础测试
1、创建一个索引
PUT /索引名/类型名/文档id
{请求体}
2、向索引中PUT值
3、name这个字段用不用指定类型呢,毕竟我们关系型数据库,是需要指定类型的
字符串类型
text 、keyword
数值类型
long、integer、short、byte、double、float、half、float、scaled
日期类型
date
te布尔值类型
boolean
二进制类型
binary
等等……
4、指定字段的类型(创建规则)
获取规则,可以通过get请求获取具体的信息
GET test2
测试
如果自己的文档字段没有自定,那么es会给我们配置默认字段类型!
扩展:通过命令ElasticSearch索引情况! 通过get _cat/ 可以获得ElasticSearch的很多信息
修改索引 提交还是使用PUT
曾经的方法:
最新办法
删除索引 通过DELETE命令实现删除,根据你的请求来判断是删除索引还是删除文档记录!
关于文档的基本操作(重点)
基本操作
1、添加一条数据
PUT /wumao/user/1
{"name":"wumao","age":21,"desc":"一顿操作猛如虎,一看工资2500","tags":["技术宅","无聊者"]
}
2、获取数据 GET
3、更新操作 POST _update
推荐使用这种更新方式
简单的搜索
GET wumao/user/1
简单的条件查询 ,可以根据默认的映射规则,产生基本的查询!
复杂操作 搜索 select(排序、分页、高亮、精准查询!)
输出结果,不想要那么多结果!select name,desc . . . .
之后使用Java操作es,所有的方法和对象就是这里面的key!
排序
分页
数据下标还是从0开始的,和学的所有数据结构是一样的!
/search/{current}/{pageSize}
布尔值查询
must (and),所有的条件都要符合 where id = 1 and name =xxx
should( or ),所有的条件都要符合 where id = 1 orname =xxx
must_not(not)
过滤器filter
gt > 大于gte >= 大于等于lt < 小于lte <= 小于等于
匹配多个条件
精确查询!
trem 查询是直接通过倒排索引指定的词条进行精确的查找的!
关于分词:
term,直接查询精确地
match,会使用分词器解析(先分析文档,通过分析的文档进行查询)
两个类型 text keyword
多个值精确匹配
高亮查询!
- 匹配
- 按条件匹配
- 精确匹配
- 区间范围匹配
- 匹配字段过滤
- 多条件查询
- 高亮查询
集成SpringBoot
找官方文档!
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.12/index.html
1、找到原生的依赖
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.13.2</version>
</dependency>
2、找对象
3、分析这个类中的方法
配置基本的项目
问题:创建项目默认的elasticsearch的默认版本是7.12.1,版本和本地不一致!
需要自己定义版本的依赖
分析源码
虽然导入了三个类,静态内部类,核心类只有一个
/*** Elasticsearch rest client configurations.** @author Stephane Nicoll*/
class ElasticsearchRestClientConfigurations {@Configuration(proxyBeanMethods = false)@ConditionalOnMissingBean(RestClientBuilder.class)static class RestClientBuilderConfiguration {@BeanRestClientBuilderCustomizer defaultRestClientBuilderCustomizer(ElasticsearchRestClientProperties properties) {return new DefaultRestClientBuilderCustomizer(properties);}//第一个bean RestClientBuilder@BeanRestClientBuilder elasticsearchRestClientBuilder(ElasticsearchRestClientProperties properties,ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {HttpHost[] hosts = properties.getUris().stream().map(this::createHttpHost).toArray(HttpHost[]::new);RestClientBuilder builder = RestClient.builder(hosts);builder.setHttpClientConfigCallback((httpClientBuilder) -> {builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(httpClientBuilder));return httpClientBuilder;});builder.setRequestConfigCallback((requestConfigBuilder) -> {builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(requestConfigBuilder));return requestConfigBuilder;});builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));return builder;}private HttpHost createHttpHost(String uri) {try {return createHttpHost(URI.create(uri));}catch (IllegalArgumentException ex) {return HttpHost.create(uri);}}private HttpHost createHttpHost(URI uri) {if (!StringUtils.hasLength(uri.getUserInfo())) {return HttpHost.create(uri.toString());}try {return HttpHost.create(new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(),uri.getQuery(), uri.getFragment()).toString());}catch (URISyntaxException ex) {throw new IllegalStateException(ex);}}}@Configuration(proxyBeanMethods = false)@ConditionalOnMissingBean(RestHighLevelClient.class)static class RestHighLevelClientConfiguration {//第二个bean RestHighLevelClient 高级客户端,后面项目会用到!@BeanRestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {return new RestHighLevelClient(restClientBuilder);}}@Configuration(proxyBeanMethods = false)@ConditionalOnClass(Sniffer.class)@ConditionalOnSingleCandidate(RestHighLevelClient.class)static class RestClientSnifferConfiguration {@Bean@ConditionalOnMissingBeanSniffer elasticsearchSniffer(RestHighLevelClient client, ElasticsearchRestClientProperties properties) {SnifferBuilder builder = Sniffer.builder(client.getLowLevelClient());PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();map.from(properties.getSniffer().getInterval()).asInt(Duration::toMillis).to(builder::setSniffIntervalMillis);map.from(properties.getSniffer().getDelayAfterFailure()).asInt(Duration::toMillis).to(builder::setSniffAfterFailureDelayMillis);return builder.build();}}static class DefaultRestClientBuilderCustomizer implements RestClientBuilderCustomizer {private static final PropertyMapper map = PropertyMapper.get();private final ElasticsearchRestClientProperties properties;DefaultRestClientBuilderCustomizer(ElasticsearchRestClientProperties properties) {this.properties = properties;}@Overridepublic void customize(RestClientBuilder builder) {}@Overridepublic void customize(HttpAsyncClientBuilder builder) {builder.setDefaultCredentialsProvider(new PropertiesCredentialsProvider(this.properties));}@Overridepublic void customize(RequestConfig.Builder builder) {map.from(this.properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis).to(builder::setConnectTimeout);map.from(this.properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis).to(builder::setSocketTimeout);}}private static class PropertiesCredentialsProvider extends BasicCredentialsProvider {PropertiesCredentialsProvider(ElasticsearchRestClientProperties properties) {if (StringUtils.hasText(properties.getUsername())) {Credentials credentials = new UsernamePasswordCredentials(properties.getUsername(),properties.getPassword());setCredentials(AuthScope.ANY, credentials);}properties.getUris().stream().map(this::toUri).filter(this::hasUserInfo).forEach(this::addUserInfoCredentials);}private URI toUri(String uri) {try {return URI.create(uri);}catch (IllegalArgumentException ex) {return null;}}private boolean hasUserInfo(URI uri) {return uri != null && StringUtils.hasLength(uri.getUserInfo());}private void addUserInfoCredentials(URI uri) {AuthScope authScope = new AuthScope(uri.getHost(), uri.getPort());Credentials credentials = createUserInfoCredentials(uri.getUserInfo());setCredentials(authScope, credentials);}private Credentials createUserInfoCredentials(String userInfo) {int delimiter = userInfo.indexOf(":");if (delimiter == -1) {return new UsernamePasswordCredentials(userInfo, null);}String username = userInfo.substring(0, delimiter);String password = userInfo.substring(delimiter + 1);return new UsernamePasswordCredentials(username, password);}}}
具体的API测试
1、创建索引
2、判断文档是否存在
3、删除索引
4、创建文档
5、CRUD文档
@SpringBootTest
class WumaoEsApiApplicationTests {@Autowired@Qualifier("restHighLevelClient")private RestHighLevelClient client;//测试创建索引 在java中所有的请求都是用Request PUT wumao_index@Testpublic void testCreateIndex() throws IOException {//1、创建索引请求CreateIndexRequest request = new CreateIndexRequest("wumao_index");//2、客户端执行请求 IndicesClient,请求后获取响应CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);System.out.println(createIndexResponse);}//测试获取索引@Testvoid testExistsIndex() throws IOException {GetIndexRequest re = new GetIndexRequest("wumao_index");boolean exists = client.indices().exists(re,RequestOptions.DEFAULT);System.out.println(exists);}//测试删除索引@Testvoid testDeleteIndex() throws IOException {DeleteIndexRequest request = new DeleteIndexRequest("wumao_index");AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);System.out.println(delete);}//添加文档@Testvoid testAddDocument() throws IOException {//创建对象User user = new User("五毛",3);//创建请求IndexRequest request = new IndexRequest("wumao_index");//设值一些规则 put /wumao_index/_doc/1request.id("1");request.timeout(TimeValue.timeValueSeconds(1));request.timeout("1s");//将我们的数据放入请求 jsonString string = JSON.toJSONString(user);request.source(string, XContentType.JSON);//客户端发送请求,获取响应的结果IndexResponse index = client.index(request, RequestOptions.DEFAULT);System.out.println(index.toString());System.out.println(index.status());//对应我们命令的返回状态}//获取文档@Testvoid testIsExists() throws IOException {//获取文档,判断是否存在 get/index/doc/1GetRequest index = new GetRequest("wumao_index", "1");//不获取返回的_source的上下文了index.fetchSourceContext(new FetchSourceContext(false));index.storedFields("_none_");boolean exists = client.exists(index, RequestOptions.DEFAULT);System.out.println(exists);}//获取文档的信息@Testvoid testGetDocument() throws IOException {GetRequest index = new GetRequest("wumao_index", "1");GetResponse fields = client.get(index, RequestOptions.DEFAULT);System.out.println(fields.getSourceAsString());System.out.println(fields);}//更新文档记录@Testvoid testUpdateDocument() throws IOException {UpdateRequest index = new UpdateRequest("wumao_index", "1");//设置超时时间index.timeout(TimeValue.timeValueSeconds(1));User user = new User("法外狂徒张三", 12);UpdateRequest doc = index.doc(JSON.toJSONString(user),XContentType.JSON);UpdateResponse update = client.update(index, RequestOptions.DEFAULT);System.out.println(update);}//删除文档记录@Testvoid testDeleteDocument() throws IOException {DeleteRequest request = new DeleteRequest("wumao_index", "1");//设置请求过期时间request.timeout("1s");DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);System.out.println(delete.status());}//特殊的,真的项目一般都是批量插入数据@Testvoid testBulkRequest() throws IOException {BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("10s");ArrayList<User> userList = new ArrayList<>();userList.add(new User("wumao",3));userList.add(new User("wumao1",23));userList.add(new User("wumao2",21));userList.add(new User("wumao3",12));userList.add(new User("wumao4",13));userList.add(new User("wumao5",23));userList.add(new User("wumao6",33));for (int i = 0; i < userList.size(); i++) {bulkRequest.add(new IndexRequest("wumao_index").source(JSON.toJSONString(userList.get(i)),XContentType.JSON));}BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk.hasFailures());//是否失败!}//查询// SearchRequest 搜索请求// SearchSourceBuilder 条件构造// HighlightBuilder 构建高亮// TermQueryBuilder 精确查询// MatchAllQueryBuilder 查询全部// xxxxQueryBuilder 对应之前的那些命令@Testvoid testSearch() throws IOException {SearchRequest request = new SearchRequest("wumao_index");//构建搜索条件SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//查询条件,我么可以使用QueryBuilders 工具类来实现//QueryBuilders.termQuery 精确查询//QueryBuilders.matchAllQuery(); 匹配所有MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();TermQueryBuilder termQuery = QueryBuilders.termQuery("name", "wumao");//查询过期时间sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));request.source(sourceBuilder);SearchResponse search = client.search(request, RequestOptions.DEFAULT);System.out.println(JSON.toJSONString(search.getHits()));for (SearchHit hit : search.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}//批量创建文档@Testvoid testBulkDocument() throws IOException {BulkRequest bulkRequest = new BulkRequest();//设置过期时间bulkRequest.timeout("60s");ArrayList<User> userList = new ArrayList<>();userList.add(new User("qinfeng",3));userList.add(new User("qinfeng1",3));userList.add(new User("qinfeng2",3));userList.add(new User("qinfeng3",3));userList.add(new User("qinfeng4",3));userList.add(new User("qinfeng5",3));for (int i = 0; i < userList.size(); i++) {bulkRequest.add(new IndexRequest("wumao_index").id(""+(i+1)).source(JSON.toJSONString(userList.get(i)),XContentType.JSON));}BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk.hasFailures());//判断是否失败}}
实战案例
- 爬虫
数据问题 数据库中获取,消息队列获取
爬取数据(获取请求返回的页面信息,筛选出我们所需要的)
<!--解析网页-->
<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.14.2</version>
</dependency>
public List<Content> parseJD(String keyWords) throws Exception {//获取请求 https://search.jd.com/Search?keyword=javaString url = "https://search.jd.com/Search?keyword="+keyWords;//解析网页 (Jsoup返回的Document就是Document对象)Document document = Jsoup.parse(new URL(url), 30000);//所有在js中使用的方法,在这里都可以使用Element element = document.getElementById("J_goodsList");ArrayList<Content> list = new ArrayList<>();//获取所有的li元素Elements elements = element.getElementsByTag("li");//这里的el就是每一个li标签for (Element el : elements) {//关于这种图片特别多的网站,都是延时加载的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.setPrice(price);list.add(content);}return list;}
前后端分离
搜索高亮
//解析数据放入到es中public Boolean parseContent(String keyWords) throws Exception {List<Content> contents = new HtmlParseUtil().parseJD(keyWords);//把查询到的数据放入到es中BulkRequest request = new BulkRequest();request.timeout("2m");for (int i = 0; i < contents.size(); i++) {System.out.println(JSON.toJSONString(contents.get(i)));request.add(new IndexRequest("jd_goods").source(JSON.toJSONString(contents.get(i)), XContentType.JSON));}BulkResponse bulkResponse = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);return !bulkResponse.hasFailures();}
//3.实现搜索高亮功能public List<Map<String,Object>> searchHighlightPage(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);//精准匹配QueryBuilders.termQuery("title",keyword);sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("title");highlightBuilder.requireFieldMatch(false); //高亮显示一个title只显示一个高亮就可以highlightBuilder.preTags("<span style='color:red'>");highlightBuilder.postTags("</span>");sourceBuilder.highlighter(highlightBuilder);//执行搜索searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//解析结果ArrayList<Map<String,Object>> list = new ArrayList<>();for (SearchHit hit : searchResponse.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;}
本篇到这里就结束了!后续还会继续更新ElasticSearch调优、ElasticSearch集群以及面试题相关的内容,
感谢诸佬的点赞和支持。
如有不足之处,还希望诸佬指出不足之处,加以修正。
再见了各位小伙伴!
ElasticSearch学习总结(基础篇,可学习,可复习)相关推荐
- MySQL学习笔记-基础篇1
MySQL 学习笔记–基础篇1 目录 MySQL 学习笔记--基础篇1 1. 数据库概述与MySQL安装 1.1 数据库概述 1.1.1 为什么要使用数据库 1.2 数据库与数据库管理系统 1.2.1 ...
- 计算机视觉面试宝典--深度学习机器学习基础篇(四)
计算机视觉面试宝典–深度学习机器学习基础篇(四) 本篇主要包含SVM支持向量机.K-Means均值以及机器学习相关常考内容等相关面试经验. SVM-支持向量机 支持向量机(support vector ...
- 【Kotlin】学习小记-基础篇
Kotlin学习小记-基础篇 Kotlin的介绍 入门基础篇 属性声明 关于val和final的小Tips 参数 1.可变参数 2.命名参数 函数返回值 1.默认返回Unit值 2.返回Nothing ...
- STM32运行深度学习指南基础篇(3)(STM32CubeMX.AI+Tensorflow)
STM32运行深度学习指南基础篇(3)(STM32CubeMX.AI+Tensorflow) 在上一篇文章中我们已经有训练好的tflite模型,接下来我们要在Clion中实现,如果是Keil的朋友可以 ...
- Redis学习笔记①基础篇_Redis快速入门
若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...
- C++ 学习 ::【基础篇:13】:C++ 类的基本成员函数:类类型成员的初始化与构造函数问题
本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇.STL 篇.高阶数据结构与算法篇,相关重点内容如下: 基础篇:类与对象(涉及C++的三大特 ...
- C++ 学习 ::【基础篇:17】:C++ 类与对象:运算符重载介绍、运算符重载函数(类内与类外区别)写法及简单设计实现
本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇.STL 篇.高阶数据结构与算法篇,相关重点内容如下: 基础篇:类与对象(涉及C++的三大特 ...
- MySQL学习笔记-基础篇2
MySQL学习笔记-基础篇2 目录 MySQL学习笔记-基础篇2 8.子查询 8.1 需求分析与问题解决 8.1.1 实际问题 8.1.2 子查询的基本使用 8.1.3 子查询的分类 8.2 单行子查 ...
- 【SQL基础学习】----基础篇(1)
前言: 存储数据的容器 在内存中(数据存在易失性,断电即数据没了): 数组 集合 磁盘(永久存储): 文件(不易管理) 数据库(持久化, ...
- 【Vulkan学习记录-基础篇-1】用Vulkan画一个三角形
好久没有更新过博客了,上半年一直忙着找实习的事情,不过现在已经入职一段时间了,也可以抽出时间来继续整理一些内容,所以最近会尽量变得勤快一点来写博客. Vulkan是新一代的图形API,具有跨平台.高性 ...
最新文章
- css表示第一个元素和最后一个元素,CSS第一个和最后一个子元素
- ios android安全性分析,Android与iOS的对比分析及Android安全技术的设计与实现
- 【转】谈谈三层架构中MODEL的作用
- [Step By Step]SAP HANA创建层次结构的属性视图(Hierarchy Attribute View)
- springboot启动流程
- 21世纪初最有影响力的20篇计算机视觉期刊论文 及 邓亚峰老师关于人脸识别方面总结
- ubuntu安装python库_Ubuntu18.04一次性升级Python所有库的方法步骤
- Thinking In Design Pattern——Unit Of Work(工作单元)模式探索
- javaweb实训第五天上午——Spring基础
- 梯度下降的线性回归用python_一元线性回归和梯度下降的python代码实现
- 用Windows Live Writer在博客园发布Post
- jsp连接MYSQL数据库教程(文字+图)
- 下载mysql驱动jar包教程
- 李宏毅机器学习——课后作业1
- 容器监控cadvisor
- 远程桌面管理助手有哪些?11款最好的远程桌面软件推荐。
- QQ客户端管理聊天记录漫游功能 | 解决经常弹窗消息漫游安全验证,QQ服务独立密码的问题
- error An unexpected error occurred: “https://registry.npmjs.org/axios
- Matlab之real和imag函数
- git:remote: [session-f044bfa6] well: Incorrect username or password (access token)