1、ElasticSearch数据准备
2、通过Java进行全文检索
3、效果展示
PUT /libary
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"book":{
"properties":{
"name":{
"type":"text",
"analyzer":"ik_max_word"
},
"price":{
"type":"double"
},
"author":{
"type":"text",
"analyzer":"ik_max_word"
},
"house":{
"type":"text",
"analyzer":"ik_max_word"
},
"desc":{
"type":"text",
"analyzer":"ik_max_word"
},
"publish":{
"type":"date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
图书数据:图书编号、书籍名、书籍价格、作者、出版社、描述、出版日期
### 图书数据:图书编号、书籍名、书籍价格、作者、出版社、描述、出版日期
POST /libary/book
{
"id":"101",
"name":"Spring实战(第4版)",
"price":78.30,
"author":"Craig Walls 沃尔斯 著,张卫滨 译",
"house":"人民邮电出版社",
"desc":"《Spring实战(第4版)》是经典的、畅销的Spring学习和实践指南。第4版针对Spring 4进行了全面更新。全书分为四部
分。第1部分介绍Spring框架的核心知识。第二部分在此基础上介绍了如何使用Spring构建Web应用程序。第三部分告别前端,介绍了
如何在应用程序的后端使用Spring。",
"publish":"2016-04-01"
}
POST /libary/book
{
"id":"102",
"name":"Spring Boot实战",
"price":41.60,
"author":"克雷格·沃斯(Craig Walls) 著,丁雪丰 译",
"house":"人民邮电出版社",
"desc":"本书以Spring应用程序开发为中心,全面讲解如何运用Spring Boot提高效率,使应用程序的开发和管理更加轻松有趣。作
者行文亲切流畅,以大量示例讲解了Spring Boot在各类情境中的应用,内容涵盖起步依赖、Spring Boot CLI、Groovy、Grails、
Actuator。对于Spring Boot开发应用中较为繁琐的内容,附录奉上整理完毕的表格,一目了然,方便读者查阅。",
"publish":"2016-09-01"
}
POST /libary/book
{
"id":"103",
"name":"Spring Cloud与Docker微服务架构实战(第2版)",
"price":72.70,
"author":"周立 著",
"house":"电子工业出版社",
"desc":"本书基于Spring Cloud Edgware RELEASE 与Docker 17.09,以指导技术团队实现微服务架构落地为宗旨,覆盖微服务理
论、微服务开发框架(Spring Cloud)及运行平台(Docker)三大主题。",
"publish":"2018-07-01"
}
POST /libary/book
{
"id":"104",
"name":"Java EE互联网轻量级框架整合开发",
"price":83.90,
"author":"杨开振,周吉文,梁华辉,谭茂华 著",
"house":"电子工业出版社",
"desc":"随着移动互联网的兴起,以Java技术为后台的互联网技术占据了市场的主导地位,而在Java互联网后台开发中,SSM框架(
Spring+Spring MVC+MyBatis)成为了主要架构,本书以此为焦点从入门到实际工作要求讲述了SSM框架的技术应用;",
"publish":"2017-07-01"
}
POST /libary/book
{
"id":"105",
"name":"Java EE框架整合开发入门到实战",
"price":64.20,
"author":"陈恒,楼偶俊,张立杰 著",
"house":"清华大学出版社",
"desc":"本书详细讲解了Java EE中Spring、Spring MVC和MyBatis三大框架(SSM)的基础知识和实际应用。为了更好地帮助读者
学习SSM框架,本书以大量案例介绍了SSM框架的基本思想、方法和技术。",
"publish":"2018-08-01"
}
POST /libary/book
{
"id":"106",
"name":"现货正版 深入理解Java虚拟机:JVM高级",
"price":50.90,
"author":"周志明 著",
"house":"机械工业出版社",
"desc":"《深入理解Java虚拟JVM高级特性与佳实践》由周志明所著,超级畅销书全新升级,第1版两年内印刷近10次,Java图书领域
公认的经典著作,繁体版台湾发行。 基于新JDK1.7,围绕内存管理、执行子系统、程序编译与优化、高效并发等核心主题对JVM进行
全面而深入的分析,深刻揭示JVM的工作原理。 以实践为导向,通过大量与实际生产环境相结合的案例展示了解决各种常见JVM问题的
技巧和佳实践。",
"publish":"2013-06-01"
}
POST /libary/book
{
"id":"107",
"name":"Java学习黄金组合套装 ",
"price":142.30,
"author":"明日科技 著",
"house":"吉林大学出版社",
"desc":"《Java项目开发实战入门》以一起来画画、通讯录系统、明日彩票预测系统、小小五子棋、企业进销存管理系统、企业QQ(
局域网版)、九宫格记忆网和铭成在线考试系统8个精选项目为案例,从趣味性和实际应用角度出发,采用了当前主流技术,读者可以
从这些项目中体验到编程的乐趣并获得实战经验。",
"publish":"2017-09-01"
}
POST /libary/book
{
"id":"108",
"name":"Java 8入门与实践实验指导及习题解析",
"price":37.80,
"author":"丁振凡 著",
"house":"水利水电出版社",
"desc":"《Java 8入门与实践实验指导及习题解析(微课视频版)》在内容体系上与笔者编写的《Java 8入门与实践(微课视频版)
》紧密配合。两本书的各章次序保持一致,目的是为每章的实践环节提供一个详细指导。每章包括知识要点、实验指导、习题解析。知
识要点部分对《Java 8入门与实践(微课视频版)》每章的知识点进行了提炼。实验指导部分包括实验目的、样例调试和编程练习。其
中样例调试包括基本训练题和综合样例题,基本训练题的目标是强化概念理解,分步启发引导学生在编程调试过程中进行自我知识总
结;综合样例题则是培养学生综合应用知识的能力。实验指导部分的编程题可供学生思考与练习。习题解析部分对《Java 8入门与实
践(微课视频版)》一书每章的习题进行了详细的解答和分析。",
"publish":"2019-05-01"
}
POST /libary/book
{
"id":"109",
"name":"web前端基础开发秘籍:HTML5 CSS3",
"price":106.40,
"author":"未来科技 著",
"house":"中国水利水电出版社",
"desc":"《HTML5+CSS3+JavaScript从入门到精通(标准版)》以基础知识、示例、实战案例相结合的方式详尽讲述了HTML、CSS、
JavaScript及目前新的前端技术,html5移动开发html5实战html5canvashtml5apphtml5入门html5动画html5揭秘html游戏html5
指南的基本知识都有涉及。全书分两大部分,共12章。",
"publish":"2017-07-01"
}
POST /libary/book
{
"id":"110",
"name":"PHP从零基础到项目实战",
"price":67.90,
"author":"未来科技 著",
"house":"中国水利水电出版社",
"desc":"《PHP从零基础到项目实战(微课视频版)》从初学者角度出发,以基础知识、示例、实战案例相结合的方式,详细介绍了使
用PHP进行网络开发、游戏开发、移动端后台开发、OA系统开发、服务器端开发等应该掌握的各方面技术。本书共24章,主要内容包括
PHP概述、安装和配置PHP运行环境、PHP语言基础、操作字符串、使用正则表达式、操作数组、使用PHP与网页交互、PHP日期和时间
处理、PHP会话处理、PHP图形图像处理、PHP文件系统处理、PHP面向对象程序设计、安装和使用MySQL、使用phpMyAdmin管理MySQL
、使用PHP操作MySQL、使用PDO操作数据库、PHP加密技术、PHP与JavaScript技术、PHP与XML技术、PHP与Ajax技术、PHP与
Socket技术、PHP错误和异常处理,最后两章通过购物网站和移动私密社区两个综合案例诠释PHP在实际项目中的具体应用。书中所有
知识都结合具体实例进行介绍,将基础知识和实例相结合,可以使读者轻松领会PHP程序开发的精髓,快速提高开发技能。",
"publish":"2019-01-01"
}
POST /libary/book
{
"id":"111",
"name":"海底两万里世界名著全10册",
"price":39.80,
"author":"让-亨利·卡西米尔·法布尔 著,徐海丽 编",
"house":"中译出版社",
"desc":"大自然中,有太多我们所不知道的事了,而它们又是客观存在的,只要你有心,就会发现另一个不一样的世界。那个世界里不
乏有趣的见闻,并且充满了惊喜,它神秘而又充满了幻想,它就是昆虫的世界。在《昆虫记》里,详细介绍了昆虫世界里的生、老、病
、死和喜、怒、哀、乐,时时让我们惊叹造物者的神奇。",
"publish":"2016-06-01"
}
POST /libary/book
{
"id":"112",
"name":"环球国家地理百科全书",
"price":137.30,
"author":"王越 编",
"house":"北京联合出版公司",
"desc":"全书以行政区划和地理位置为纲,将各大洲以地理分布划分为若干国家单元,各单元中均以国家或地区为单位,为读者详细地
介绍了世界各地精彩纷呈的方方面面。此外,我们为了将世界地理之美表达的更为全面和真实,特地在每卷书的最后加了一部分地理美
文,让你在百科知识看到乏味之时,享受一下异样的地理之美。",
"publish":"2016-06-01"
}
POST /libary/book
{
"id":"113",
"name":"福尔摩斯探案集全集10册",
"price":128.80,
"author":null,
"house":"山东友谊出版社",
"desc":null,
"publish":"2010-06-01"
}
POST /libary/book
{
"id":"114",
"name":"新华字典(第11版)",
"price":16.90,
"author":"商务印书馆 编",
"house":"商务印书馆",
"desc":"《新华字典》是新中国第一部现代汉语字典,首次出版于1953年,原由新华辞书社编写,著名语言文字学家魏建功先生主持
编写工作。1956年,新华辞书社并人当时的中国科学院语言研究所(1977年改属中国社会科学院)词典编辑室。《新华字典》历经多
次修订出版,深受广大读者欢迎。在第11版出版之际,谨向为《新华字典》的编写、修订工作做出重要贡献的前辈学者们致以崇高的敬
意。",
"publish":"2011-06-01"
}
POST /libary/book
{
"id":"115",
"name":"古代汉语词典",
"price":55.20,
"author":"商务印书馆辞书研究中心 编",
"house":"商务印书馆",
"desc":"《古代汉语词典》自1998年出版以来,深受读者欢迎。至今已经过去了15年,有必要进行一次系统的修订,把质量提高到一
个新的水平。",
"publish":"2014-05-01"
}
POST /libary/book
{
"id":"116",
"name":"一看就停不下来的中国史",
"price":52.60,
"author":"最爱君 著",
"house":"台海出版社",
"desc":"硬气文人、戏精政客、失意将军、求生商人、谜案新解。在《一看就停不下来的中国史》中,我们会见到那些留名千古的人物
,但读到的不再是猎奇,不再是抽离了人性的空洞规律,而是深伏于文字之下的,那呼之欲出的内在驱动力量。",
"publish":"2018-10-01"
}
POST /libary/book
{
"id":"117",
"name":"Silent Spring寂静的春天 英文原版",
"price":144.30,
"author":"Rachel Carson(蕾切尔·卡森)著",
"house":"Houghton Mifflin Harcourt",
"desc":"《寂静的春天》1962年在美国问世时,是一本很有争议的书。它那惊世骇俗的关于农药危害人类环境的预言,不仅受到与之
利害攸关的生产与经济部门的猛烈抨击,而且也强烈震撼了社会广大民众。你若有心去翻阅本世纪60年代以前的报纸或书刊,你将会发
现几乎找不到“环境保护”这个词。",
"publish":"2003-10-23"
}
POST /libary/book
{
"id":"118",
"name":"Baby Loves Spring 宝宝爱春天 纸板翻翻书",
"price":23.50,
"author":"Carson卡森 著",
"house":"Little Simon",
"desc":"儿童读物 Baby Loves Spring ",
"publish":"2009-10-23"
}
Dao接口定义:
package com.jeebuilder.modules.generator.dao;
import com.jeebuilder.modules.generator.entity.BookEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
/**
*
*
* @author jerrychen
* @email [email protected]
* @date 2019-05-21 15:06:35
*/
@Mapper
public interface BookDao extends BaseMapper {
public List
Dao实现类:
package com.jeebuilder.modules.generator.dao.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Repository;
import com.jeebuilder.common.utils.ClientUtils;
@Repository
public class BookDaoImpl {
private TransportClient client = ClientUtils.getClient();
/**
* 1 0 -10
* 2 10 - 10
* @param page
* @param limit
* @return
*/
public List> queryAllBook(Integer page,Integer limit){
//查询所有图书信息
List> bookList = new ArrayList<>();
//指定一个index和type
SearchRequestBuilder search = client.prepareSearch("libary").setTypes("book");
//使用原生排序优化性能
search.addSort("_doc", SortOrder.ASC);
//默认是查询所有
search.setQuery(QueryBuilders.queryStringQuery("*:*")).setFrom((page-1)*limit).setSize(limit);
//获得首次的查询结果
SearchResponse scrollResp=search.get();
//读取结果集数据
for (SearchHit hit : scrollResp.getHits().getHits()) {
bookList.add(hit.getSourceAsMap());
}
return bookList;
}
public List> queryByString( String str,Integer page,Integer limit){
//查询所有图书信息
List> bookList = new ArrayList<>();
//查询爱好或地址或姓名中包含"唱歌"的用户
//指定一个index和type
SearchRequestBuilder search = client.prepareSearch("libary").setTypes("book");
//使用原生排序优化性能
search.addSort("_doc", SortOrder.ASC);
//默认是查询所有
search.setQuery(QueryBuilders.multiMatchQuery(str, "desc","house","name")).setFrom((page-1)*limit).setSize(limit);
//设置高亮显示
HighlightBuilder highlightBuilder = new HighlightBuilder().field("*").requireFieldMatch(false);
highlightBuilder.preTags("");
highlightBuilder.postTags("");
search.highlighter(highlightBuilder);
//获得首次的查询结果
SearchResponse scrollResp=search.get();
//读取结果集数据
for (SearchHit hit : scrollResp.getHits().getHits()) {
Map sourceAsMap = hit.getSourceAsMap();
//处理高亮片段
Map highlightFields = hit.getHighlightFields();
HighlightField nameField = highlightFields.get("name");
HighlightField descField = highlightFields.get("desc");
if(nameField!=null){
org.elasticsearch.common.text.Text[] fragments = nameField.fragments();
String nameTmp ="";
for(org.elasticsearch.common.text.Text text:fragments){
nameTmp+=text;
}
//将高亮片段组装到结果中去
sourceAsMap.put("name",nameTmp);
}
if(descField!=null){
org.elasticsearch.common.text.Text[] fragments = descField.fragments();
String nameTmp ="";
for(org.elasticsearch.common.text.Text text:fragments){
nameTmp+=text;
}
//将高亮片段组装到结果中去
sourceAsMap.put("desc",nameTmp);
}
bookList.add(sourceAsMap);
}
return bookList;
}
public Integer queryBookCounts(String str) {
//查询所有图书信息
List> bookList = new ArrayList<>();
//指定一个index和type
SearchRequestBuilder search = client.prepareSearch("libary").setTypes("book");
//使用原生排序优化性能
search.addSort("_doc", SortOrder.ASC);
//默认是查询所有
if (str == null || str.equals("")) {
search.setQuery(QueryBuilders.queryStringQuery("*:*"));
}else {
search.setQuery(QueryBuilders.multiMatchQuery(str, "desc","house","name"));
}
//设置 search context 维护1分钟的有效期
search.setScroll(TimeValue.timeValueMinutes(1));
//获得首次的查询结果
SearchResponse scrollResp=search.get();
do {
//读取结果集数据
for (SearchHit hit : scrollResp.getHits().getHits()) {
bookList.add(hit.getSourceAsMap());
}
//将scorllId循环传递
scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(TimeValue.timeValueMinutes(1)).execute().actionGet();
//当searchHits的数组为空的时候结束循环,至此数据全部读取完毕
} while(scrollResp.getHits().getHits().length != 0);
return bookList.size();
}
}
Service接口:
package com.jeebuilder.modules.generator.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jeebuilder.common.utils.PageUtils;
import com.jeebuilder.modules.generator.entity.BookEntity;
import java.util.List;
import java.util.Map;
/**
*
*
* @author jerrychen
* @email [email protected]
* @date 2019-05-21 15:06:35
*/
public interface BookService extends IService {
//PageUtils queryPage(Map params);
public List> queryAllBook(Map params);
public Integer queryBookCounts(Map params);
}
Service实现类
package com.jeebuilder.modules.generator.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeebuilder.common.utils.PageUtils;
import com.jeebuilder.common.utils.Query;
import com.jeebuilder.modules.generator.dao.BookDao;
import com.jeebuilder.modules.generator.dao.impl.BookDaoImpl;
import com.jeebuilder.modules.generator.entity.BookEntity;
import com.jeebuilder.modules.generator.service.BookService;
@Service("bookService")
public class BookServiceImpl extends ServiceImpl implements BookService {
@Autowired
private BookDaoImpl bookDaoImpl;
/*
* @Override public PageUtils queryPage(Map params) {
* QueryWrapper queryWrapper = new QueryWrapper<>(); String key =
* params.get("key").toString(); // 如果查询条件的值不为空,就添加 like 关键字 if
* (StringUtils.isNotEmpty(key)){
* queryWrapper.like(params.get("column").toString(),params.get("key")); }
* IPage page = this.page( new Query().getPage(params),
* queryWrapper );
*
* return new PageUtils(page); }
*/
public List> queryAllBook(Map params) {
String str = (String) params.get("key");
Integer page = Integer.parseInt((String)params.get("page")) ;
Integer limit = Integer.parseInt((String)params.get("limit"));
if (str == null || str.equals("")) {
return bookDaoImpl.queryAllBook(page,limit);
} else {
return bookDaoImpl.queryByString(str,page,limit);
}
}
@Override
public Integer queryBookCounts(Map params) {
// TODO Auto-generated method stub
String str = (String) params.get("key");
return bookDaoImpl.queryBookCounts(str);
}
}
package com.jeebuilder.modules.generator.controller;
import java.util.HashMap;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.jeebuilder.common.utils.PageUtils;
import com.jeebuilder.common.utils.R;
import com.jeebuilder.modules.generator.service.BookService;
import io.swagger.models.auth.In;
/**
*
*
* @author jerrychen
* @email [email protected]
* @date 2019-05-21 15:06:35
*/
@RestController
@RequestMapping("generator/book")
public class BookController {
@Autowired
private BookService bookService;
/**
* 列表
*/
@RequestMapping("/list")
@RequiresPermissions("generator:book:list")
public R list(@RequestParam Map params) {
// PageUtils page = bookService.queryPage(params);
Map map = new HashMap<>();
// 放置查询的数据
map.put("list", bookService.queryAllBook(params));
Integer totalCount = bookService.queryBookCounts(params);
Integer pageSize = Integer.parseInt((String) params.get("limit"));
Integer totalPage = totalCount / pageSize;
if (totalCount % 10 != 0) {
totalPage++;
}
// 放置总数量
map.put("totalCount", totalCount);
// 放置页码
map.put("pageSize", pageSize);
// 放置总页数
map.put("totalPage", totalPage);
// 放置当前页
//map.put("currPage", Integer.parseInt((String) params.get("currPage")));
return R.ok().put("page", map);
}
}
package com.jeebuilder.common.utils;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
public class ClientUtils {
/**
* 创建访问es服务器的客户端对象
* @return TransportClient
*/
public static TransportClient getClient() {
//指定ES集群
Settings settings = Settings.builder().put("cluster.name", "myes").build();
//创建访问es服务器的客户端
TransportClient client = null;
try {
client = new PreBuiltTransportClient(settings).
addTransportAddress(new TransportAddress(
InetAddress.getByName("192.168.34.64"),9300));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return client;
}
}
ort.client.PreBuiltTransportClient;
public class ClientUtils {
/**
* 创建访问es服务器的客户端对象
* @return TransportClient
*/
public static TransportClient getClient() {
//指定ES集群
Settings settings = Settings.builder().put("cluster.name", "myes").build();
//创建访问es服务器的客户端
TransportClient client = null;
try {
client = new PreBuiltTransportClient(settings).
addTransportAddress(new TransportAddress(
InetAddress.getByName("192.168.34.64"),9300));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return client;
}
}
# 3、效果展示
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210425151200601.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppbnRpYW56aGVuZw==,size_16,color_FFFFFF,t_70#pic_center)