全文检索
全文种类
检索的示意图
正向查询
说明:将全部的数据进行检索.需要的数据一个一个的对比.知道查找成功.缺点:
这样的检索速度会很慢
特点:需要一个一个的循环遍历.直到找到数据
倒排索引
说明:索引的出现,可以大大提高检索的效率.
先查询商品的索引关键字.之后将商品信息直接返回.这种方式叫做倒排索引
Lucene
介绍
入门案例
<!-- 全文检索lucene -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.10.2</version>
</dependency>
<!-- IK分词器 -->
<dependency>
<groupId>org.wltea.analyzer</groupId>
<artifactId>ik-analyzer</artifactId>
<version>2012FF_u1</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>5.2.1</version>
</dependency>
<!-- 爬虫jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.9.1</version>
</dependency>
创建检索文件
说明:通过索引生成器可以为文档创建索引,但是索引不能被直接查看,所以通过工具查看索引文件.
/**
* 1.需求 需要为一篇文章创建索引
* 步骤:
* 1.准备索引存放的地址 当前项目/index/
* 2.编辑索引的分词器 (标准分词器,ik分词) ik分词器更加适合中国人的语意
* 3.准备文档,其中包含了用户的数据信息.
* 4.通过索引的创建为文档创建不同的索引词
*
* 注意事项:
* TextField:可以将内部的信息进行索引分词
* 李白乘舟江欲行 ~~~~李 白 乘 舟 ...
* StringField:
* 李白乘舟江欲行~~~~~李白乘舟江欲行
* @throws IOException
*/
@Test
public void test01() throws IOException{
//创建索引文件存放目录 会在当前工程下建立index目录
Directory directory = FSDirectory.open(new File("./index"));
//定义分词器 定义标准分词器 对英文友好 对中文很差劲
//Analyzer analyzer = new StandardAnalyzer();
//切换中文分词器 外国人写的 效果几乎没有
//Analyzer analyzer = new ChineseAnalyzer();
//是国人开发的
Analyzer analyzer = new IKAnalyzer();
//创建配置文件 定义版本号
IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
//创建索引文件
IndexWriter indexWriter = new IndexWriter(directory, conf);
//创建文档对象:
Document document = new Document();
/**
* 参数名称:
* id :属性字段名称 value值 Store 表示是否存储 yes表示存入
* LongField 检索的关键字类型
*/
document.add(new LongField("id", 5025991L, Store.YES));
document.add(new TextField("title", "vivo X20 全面屏双摄拍照手机 4GB+64GB 磨砂黑 移动联通电信全网通4G手机 双卡双待 ", Store.YES));
document.add(new TextField("sellPoint", "游戏免打扰,畅快体验,带你吃鸡、上王者!高清全面屏,尊享Hi-Fi音质,更有面部识别+指纹双解锁!", Store.YES));
document.add(new DoubleField("price", 2988.00, Store.YES));
document.add(new TextField("itemDesc", "分辨率:2160*1080分辨后置摄像头:2x1200万像素+500万像素(2400万感光单元)前置摄像头:2x1200万像素(2400万感光单元) 核 数:八核", Store.YES));
//将索引文件写入到文档中
indexWriter.addDocument(document);
//需要管理流 否则索引不能创建
indexWriter.close();
}
根据索引查询数据
@Test
public void seracher() throws IOException{
Directory directory = FSDirectory.open(new File("./index"));
//创建检索文件
IndexSearcher indexSearcher = new IndexSearcher(IndexReader.open(directory));
//创建查询条件 Term表示分组
Query query = new TermQuery(new Term("title", "手机"));
//查询 results 表示最顶端的20条记录数
TopDocs docs = indexSearcher.search(query, 20);
//访问总数
System.out.println("数据访问的总数:"+docs.totalHits);
//获取文章的得分
for ( ScoreDoc scoreDoc : docs.scoreDocs) {
System.out.println("获取文章的得分:"+scoreDoc.score); //分数越高 越靠前
int index = scoreDoc.doc; //获取索引值
//获取文章内容
Document document = indexSearcher.doc(index);
//输出文章内容
System.out.println("标题:"+document.get("title"));
System.out.println("卖点:"+document.get("sellPoint"));
System.out.println("价格:"+document.get("price"));
System.out.println("描述信息:"+document.get("itemDesc"));
}
directory.close();
}
创建索引的高效的方式
问题:
说明:
根据索引的创建方式,如果需要为tb_item表创建索引.如何实现??
笨方法:
循环遍历全部的tb_item表
根据每一个的Item信息创建索引
弊端:
如果商品的数量众多,循环遍历的时间会很长.
如果商品的数量发生了改变,那么索引创建非常繁琐
Solr介绍
Solr的优点:
1.支持为数据库中的表整表创建索引.
2.能够支持为新的数据创建索引.(自动的) 但是有一个时效期(人为规定的)
3.支付Java对象的返回
搭建Solr
服务器搭建
安装JDK
说明:使用JDK1.7搭建Solr会有问题.所以使用jdk1.8完成
创建文件夹
配置JDK1.8
配置环境变量
说明:找到JDK的根目录
说明:让环境变量立即生效
Solr安装
导入Solr安装jar包
说明:将solr导入.将文件解压
启动solr
说明:如果solr启动成功可以通过8983访问
访问测试:
Solr的搭建要素
Solr的作用
说明:通过Solr实现为整个的数据中的Item表创建索引.通过Solr的方式效率更高
Solr引入数据库
1.创建数据库连接时名称必须为jt
2.说明:Solr要求.导入数据库时,必须在指定的文件夹下添加配置文件
引入Solr的配置文件
查找路径
cd /usr/local/src/solr-5.2.1/server/solr
进入到solr目录中创建指定的文件夹
2.创建文件夹
说明:在图上的目录下创建文件夹 jt
在jt目录下创建文件夹 conf和data
mkdir jt
mkdir jt/conf
mkdir jt/data
创建以后的结果图
配置文件介绍
说明:
说明:通过Solr连接数据库值,需要进行具体的配置.需要执行那张表需要创建索引.创建索引的分组和数据类型.连接数据的地址和端口都需要进行执行.
DIH
dih-config.xml
修改配置文件中的IP地址
导入配置文件
说明:
将课前资料中的jt/conf/文件全部导入solr中conf文件下
导入jar包
说明:将DIHjar包文件下载
最后结果:
说明:存入到lib下
/usr/local/src/solr-5.2.1/server/solr-webapp/webapp/WEB-INF/lib下
引入ik分词的文件
引入IK分词器的jar包文件
在/usr/local/src/solr-5.2.1/server/solr-webapp/webapp/WEB-INF下创建 classes文件夹
引入课前资料中的class文件
将classes中的文件引入
重启solr
./solr stop –all #停止服务
./solr start #启动服务
./solr restart #重启服务
导入数据库文件
连接测试
全库导入
查询关键字
全文检索实现
Jt-web检索
分析页面结构
说明:当通过检索窗口查询数据时,会报404,编辑Controller实现数据查询
@Controller
public class SearchController {
@Autowired
private SearchService searchService;
//url=search.html?q=华为 get提交
@RequestMapping("/search")
public String findItemByKey(@RequestParam("q")String keyword,
Model model){
//由于get提交中文必定乱码
try {
keyword = new String(keyword.getBytes("ISO-8859-1"), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
//根据关键字查询Solr获取数据
List<Item> itemList = searchService.findItemByKey(keyword);
//返回给页面关键字
model.addAttribute("query", keyword);
model.addAttribute("itemList", itemList);
return "search";
}
编辑Dubb配置文件
编辑dubbo的消费者配置文件,添加检索的Service
<!--添加检索的Service -->
<dubbo:reference check="false" id="searchService"
interface="com.jt.dubbo.service.SearchService"
timeout="20000"/>
构建jt-bubbo
引入jar包文件
<!-- 全文检索lucene -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.2.1</version>
</dependency>
<!-- IK分词器 -->
<dependency>
<groupId>org.wltea.analyzer</groupId>
<artifactId>ik-analyzer</artifactId>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>5.2.1</version>
</dependency>
<!-- 爬虫jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.9.1</version>
</dependency>
构建POJO
新建接口文件
将jt-bubbo项目打包
构建全网检索后台
构建项目
构建web项目
修改JDK/配置文件/web.xml/tomcat插件
1.删除多余的配置文件
2.修改spring的配置文件
3.添加tomcat插件
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8097</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
4.导入依赖文件
5.配置tomcat插件
添加solr的配置文件
引入properties
引入Solr的配置文件
编辑Service实现类
public class SearchServiceImpl implements SearchService {
//需要通过Solr实现数据的查询 ,需要引入配置文件
@Autowired
private HttpSolrServer httpSolrServer;
@Override
public List<Item> findItemByKey(String keyword) {
//定义查询
SolrQuery query = new SolrQuery();
//设定查询的关键字
query.setQuery(keyword);
//设定分页的参数
query.setStart(0);
query.setRows(20);
try {
//solr根据查询条件实现查询
QueryResponse queryResponse = httpSolrServer.query(query);
//获取结果集对象
List<Item> itemList = queryResponse.getBeans(Item.class);
return itemList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
添加提供者的配置文件
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="jt-search" />
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://192.168.126.145:2181"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20883" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.jt.dubbo.service.SearchService"
ref="searchService" />
<!-- 具体的实现bean -->
<bean id="searchService" class="com.jt.search.service.SearchServiceImpl" />
Solr查询转向
转向分析
说明:
由于jt-search通过索引查询数据时,需要远程访问Solr服务器.所以需要通过nginx+host文件实现url转向
修改nginx
#配置全文检索服务器solr.jt.com
server {
listen 80;
server_name solr.jt.com;
location / {
proxy_pass http://192.168.126.146:8983;
}
}
重新启动nginx
修改Host文件
# 京淘电商环境
127.0.0.1 image.jt.com
127.0.0.1 manage.jt.com
127.0.0.1 www.jt.com
127.0.0.1 sso.jt.com
127.0.0.1 cart.jt.com
127.0.0.1 order.jt.com
127.0.0.1 solr.jt.com
修改search.jsp
说明:替换课前资料的search.jsp
因为需要需要发送访问信息
将1000修改为100