Compass 更智能的搜索引擎(3)--高亮,排序,过滤以及各种搜索
要想使得一个搜索系统更加的完美,查询精确度和页面显示算是其中比较重要的两个方面。今天,我们就来谈谈怎么使得我们的搜索系统更加的完美。
关于分词
分词的好坏直接关系到我们的查询系统的精准度。所以一个更加适合的分词方式很重要。对于中文而言,更是如此。
Compass配置分词器简直是不能再简单了。我这里使用一个中科院研制的一个高效中文分词器。JE-Analysis,
下载地址
配置
我们使用xml的方式对分词器进行配置。
导入刚才下载的jar包之后,我们可以在项目的依赖中找到如图所示信息。
右键红色区域文件,点击copy qualified name。然后配置成如下面貌即可。
<?xml version="1.0" encoding="UTF-8" ?>
<compass-core-config xmlns="http://www.compass-project.org/schema/core-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.compass-project.org/schema/core-config
http://www.compass-project.org/schema/compass-core-config-2.2.xsd">
<compass name="default">
<!-- 连接信息,好比数据库的连接信息 -->
<connection>
<file path="./indexDir/" />
</connection>
<!-- 映射信息,好比Hibernate的映射关系 -->
<mappings>
<class name="domain.Article" />
</mappings>
<!-- 分词器以及高亮器的配置 -->
<settings>
<!-- 分词器的配置,可选择中文的 -->
<setting name="compass.engine.amalyzer.default.type" value="jeasy.analysis.MMAnalyzer" />
</settings>
</compass>
</compass-core-config>
好了,大功告成了。
关于高亮
对于高亮而言,我们其实并未真正的改变原始数据,而是将取出来的数据进行了一些包装而已。这样影响的仅仅是显示在我们的页面上数据。
高亮在Compass中更加方便,如下:
<?xml version="1.0" encoding="UTF-8" ?>
<compass-core-config xmlns="http://www.compass-project.org/schema/core-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.compass-project.org/schema/core-config
http://www.compass-project.org/schema/compass-core-config-2.2.xsd">
<compass name="default">
<!-- 连接信息,好比数据库的连接信息 -->
<connection>
<file path="./indexDir/" />
</connection>
<!-- 映射信息,好比Hibernate的映射关系 -->
<mappings>
<class name="domain.Article" />
</mappings>
<!-- 分词器以及高亮器的配置 -->
<settings>
<!-- 分词器的配置,可选择中文的 -->
<setting name="compass.engine.amalyzer.default.type" value="jeasy.analysis.MMAnalyzer" />
<!-- 高亮器前缀 -->
<setting name="compass.engine.highlighter.default.formatter.simple.pre" value="<font color='red' >" />
<!-- 高亮器后缀 -->
<setting name="compass.engine.highlighter.default.formatter.simple.post" value="</font>" />
<!-- 高亮器摘要的长度 -->
<setting name="compass.engine.highlighter.default.fragmenter.simple.size" value="100" />
</settings>
</compass>
</compass-core-config>
关于排序
类比国内某搜索引擎,排序其实并不公平。我们可以认为的控制排序,Compass亦是如此。
原理
不管是Compass还是数据库,我们都会通过冗余字段来提高检索速度。或者进行排序。所以我们会在bean对象中添加一个冗余字段来帮助我们对数据进行排序操作。
冗余字段
/**
* @Date 2016年8月2日
*
* @author Administrator
*/
package domain;
import org.compass.annotations.ExcludeFromAll;
import org.compass.annotations.Index;
import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableBoostProperty;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.compass.annotations.Store;
/**
*
* Compass的映射配置要求
*
* 在实体类上面有一个@Searchable注解<br>
*
* 在属性上面,至少有一个有@SearchableId
*
* 其他的属性只需要是@SearchableProperty即可
*
*
*
* @author 郭瑞彪
*/
@Searchable
public class Article {
@SearchableId
private Integer id;
// @SearchableProperty(store = Store.YES, index =
// Index.ANALYZED,,excludeFromAll=ExcludeFromAll.YES)查询的时候就会排除此项来进行查询操作
@SearchableProperty(store = Store.YES, index = Index.ANALYZED)
private String title;
@SearchableProperty(store = Store.YES, index = Index.ANALYZED)
private String content;
////////////////////////////////////////
// 如果要想改变查询结果的顺序,这个bean里面就应该有一个记录boostValue的值,这样使用的时候在具体的结果集对象上进行修改即可
@SearchableBoostProperty
private float boostValue = 1F;
////////////////////////////////////////
public float getBoostValue() {
return boostValue;
}
public void setBoostValue(float boostValue) {
this.boostValue = boostValue;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
@Override
public String toString() {
return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
使用方式
我们在存储数据的时候就可以指定某一个对象的权重了。即设置刚才的serBoostValue。这样在我们获取数据的时候,就会获得排序的数据。
测试排序
@Test
public void testBoostValueSearch() throws Exception {
String queryString = "lucene";
// 查询,得到结果
List<Article> articles = new ArrayList<Article>();
// 建立索引
Compass compassSessionFactory = CompassUtils.getCompassSessionFactory();
CompassSession session = compassSessionFactory.openSession();
CompassTransaction tx = session.beginTransaction();
CompassHits hits = session.find(queryString);
// 处理结果
for (int i = 0; i < hits.length(); i++) {
Article a = (Article) hits.data(i);
if (i == 0)
a.setBoostValue(2F);
articles.add(a);
}
tx.commit();
session.close();
// 显示结果
System.out.println(articles.toString());
for (Article a : articles) {
System.out.println("-----------搜索结果如下-----------------");
System.out.println(">>>id: " + a.getId());
System.out.println(">>>title:" + a.getTitle());
System.out.println(">>>content:" + a.getContent());
}
}
关于过滤
原理
过滤的话,无非就是要哪一段数据,不要那一段数据。这自然是关乎到查询方式的变化,同样Compass就是基于这么个理念,赋予query对象新的filter。从而实现过滤操作。过滤的实现,同样要依赖于一个冗余字段。(需要在这个字段上声明@SearchableProperty注解)
冗余字段
/**
* @Date 2016年8月2日
*
* @author Administrator
*/
package domain;
import org.compass.annotations.ExcludeFromAll;
import org.compass.annotations.Index;
import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableBoostProperty;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.compass.annotations.Store;
/**
*
* Compass的映射配置要求
*
* 在实体类上面有一个@Searchable注解<br>
*
* 在属性上面,至少有一个有@SearchableId
*
* 其他的属性只需要是@SearchableProperty即可
*
*
*
* @author 郭瑞彪
*/
@Searchable
public class Article {
@SearchableId
private Integer id;
// @SearchableProperty(store = Store.YES, index =
// Index.ANALYZED,,excludeFromAll=ExcludeFromAll.YES)查询的时候就会排除此项来进行查询操作
@SearchableProperty(store = Store.YES, index = Index.ANALYZED)
private String title;
@SearchableProperty(store = Store.YES, index = Index.ANALYZED)
private String content;
////////////////////////////////////////
// 为了过滤器所需
@SearchableProperty(store = Store.YES, index = Index.ANALYZED)
private int filmeta;
public int getFilmeta() {
return filmeta;
}
public void setFilmeta(int filmeta) {
this.filmeta = filmeta;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
@Override
public String toString() {
return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
如何使用
使用的时候需要将过滤信息附加到查询对象query上,这样才能生效。
CompassQuery query = null;
CompassQueryFilter filter = null;
filter = session.queryFilterBuilder().between("filmeta", 3, 7, true, true);
query=session.queryBuilder().queryString(queryString).toQuery();
query.setFilter(filter);
测试过滤
@Test
public void testFilterSearch() throws Exception {
String queryString = "lucene";
// 查询,得到结果
List<Article> articles = new ArrayList<Article>();
// 建立索引
Compass compassSessionFactory = CompassUtils.getCompassSessionFactory();
CompassSession session = compassSessionFactory.openSession();
CompassTransaction tx = session.beginTransaction();
CompassHits hits = null;
CompassQuery query = null;
CompassQueryFilter filter = null;
// 构建查询对象,我们可以使用这样的queryBuilder方式创建出各式各样的查询方式,如布尔查询,关键词查询,短语查询,模糊查询等等
filter = session.queryFilterBuilder().between("filmeta", 3, 7, true, true);
query = session.queryBuilder().queryString(queryString).toQuery();
query.setFilter(filter);
hits = query.hits();
// 处理结果
for (int i = 0; i < hits.length(); i++) {
Article a = (Article) hits.data(i);
if (i == 0)
a.setBoostValue(2F);
articles.add(a);
}
tx.commit();
session.close();
// 显示结果
System.out.println(articles.toString());
for (Article a : articles) {
System.out.println("-----------搜索结果如下-----------------");
System.out.println(">>>id: " + a.getId());
System.out.println(">>>title:" + a.getTitle());
System.out.println(">>>content:" + a.getContent());
}
}
关于查询
在Compass中,查询操作更是方便,我们只需要调用相关的API即可。如下图
不难看出,各种查询的底层就是基于过滤来实现的,所以我们可以一句过滤的操作来实现我们的各种查询需求。
总结
经过了这两天的搜索引擎框架的学习,基本上我们可以开发出适合自己项目需求的站内搜索或者全文搜索了。至此,本系列学习也到此结束。
如果我的这些文章恰好给对此迷茫的你一点灵光,我就非常的欣慰了。
:-)
Compass 更智能的搜索引擎(3)--高亮,排序,过滤以及各种搜索的更多相关文章
- Compass 更智能的搜索引擎(2)--进阶
经过了Compass 更智能的搜索引擎(1)–入门的学习,想必对于Compass的使用有了更深的认识了吧.下面谈点更加切合实际开发的东西.那就是CRUD. 面向对象的分页 dao层实现 代码释义 优点 ...
- Compass 更智能的搜索引擎(1)--入门
学完了前面的Lucene系列教程: 全文检索 Lucene(1)–入门 全文检索 Lucene(2)–进阶 全文检索 Lucene(3)–分页 全文检索 Lucene(4)–高亮 Lucene确实是个 ...
- iPad版微信终于来临了 微信5.4版搜索更智能 转账就是发消息
等待甚久的iPad版微信终于来临了!昨日微信iOS版本更新至5.4.0.16,新增功能包括搜索公众号.识别图中二维码.面对面收钱,同时适配iPad.(微信5.4安卓版重回ios风格 导航菜单都放底栏位 ...
- C# .NET更智能的数据库操作的封装
前述: 对数据库操作的封装,相信网络上已经有一大堆,ORM框架,或者是.NET本身的EF,都很好的支持数据库操作.这篇文章是分享自己所思考的,对数据库操作的简单封装.我对于这篇文章,认为被浏览者所关注 ...
- 使用OpenAPI构建更智能的API
像OpenAPI这样的API描述规范是一个关键工具,您应该尽可能地将其好好掌握,记录和执行API的工作由计算机和开发人员完成:OpenAPI 3.0现在允许额外的表现力,可以让机器为我们做更多有用的工 ...
- Win10系统升级更新方式将会更智能
使用Win10系统的你肯定遇到过在工作时开始自动更新而不得不搁置工作的情况,想必你也已经被Win10系统的自动更新折磨不已,不过这种情况将会马上得到改观. 微软现在已经开始寻找更智能的版本升级更新方式 ...
- 从程序到系统:建立一个更智能的世界——记Joseph Sifakis“21世纪的计算”大会主题演讲
Sifakis"21世纪的计算"大会主题演讲" title="从程序到系统:建立一个更智能的世界--记Joseph Sifakis"21世纪的计算&q ...
- 微软Project Oxford帮助开发人员创建更智能的应用
Oxford帮助开发人员创建更智能的应用" title="微软Project Oxford帮助开发人员创建更智能的应用"> 假设你是一名对关于健身的应用充满奇思妙想 ...
- AI剪辑和自定义UI,打造更智能的剪辑体验
为满足开发者构建高效的应用内视频编辑能力,7月的HMS Core 6.0 推出了视频编辑服务(Video Editor Kit),一站式的视频处理能力获得了积极反响.同时,我们也关注到开发者需要集成丰 ...
随机推荐
- rocketmq番外篇(一):开发命令行
匠心零度 转载请注明原创出处,谢谢! 说在前面 虽然是以rocketmq引出的开发命令行,但是任何java应用如果需要都可以借鉴引用,也是通用技术. 主题 rocketmq使用例子 Apache Co ...
- BST讲解
BST 第一步,什么是BST,所谓BST就是满足一种特定性质的二叉树,这个性质一般情况是当前节点的权值比他的左子树的所有点的权值大,比他的右子树的所有点的权值小,满足这样性质的二叉树就称为BST,下面 ...
- .NET Core2.0+MVC 用Redis/Memory+cookie实现的sso单点登录
之前发布过使用session+cookie实现的单点登录,博主个人用的很不舒服,为什么呢,博主自己测试的时候,通过修改host的方法,在本机发布了三个站点,但是,经过测试,发现,三个站点使用的sess ...
- python打造一个Mysql数字类型注入脚本(1)
前言: 总是想写一个sql注入脚本,但是之前的那些都不行. 这次做好了准备,然后嘿嘿嘿. 准备: sql注入的基础知识 熟悉怎么判断 正文: 思路概念图: 这里我没有限制用户输入,不限制的话可能会 @ ...
- 【BZOJ2186】【SDOI2008】沙拉公主的困惑
Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁 ...
- hdu5651 xiaoxin juju needs help(逆元)
xiaoxin juju needs help Accepts: 150 Submissions: 966 Time Limit: 2000/1000 MS (Java/Others) Mem ...
- oracle 分页查询数据重复问题
最近在做项目的时候发现一个问题,oracle 在查询分页数据的时候,有几条数据重复查询了,并且有几条数据在分页的时候消失了.百度了一下发现,ORACLE 在查询数据的时候返回的行不是固定的,他只是按照 ...
- Ubuntu16 编译源码安装MXNet 可变卷积Deformable-ConvNets GPU版
[引言]最近接手了公司的关于虫子识别的项目,使用MXNet框架开发,但是实际用的是Deformable-ConvNets. Deformable-ConvNets为微软研究研究院提出的可变卷积网络,可 ...
- Python3玩转儿 机器学习(4)
jupyternotebook 的使用方法¶ 最基本的使用¶ In [1]: 1+2 Out[1]: 3 菜单树¶ File¶ |------> New Notebook --- ...
- ArrayList add方法的实现之扩容
初探ArrayList的1.5倍扩容 add方法是通过在list的尾部追加元素的方法,添加数据的. 其中,调用了一个叫ensureCapacityInternal方法,实现list的容量换算等: 注意 ...