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="&lt;font color='red' &gt;" />
            <!-- 高亮器后缀 -->
            <setting name="compass.engine.highlighter.default.formatter.simple.post" value="&lt;/font&gt;" />
            <!-- 高亮器摘要的长度 -->
            <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即可。如下图
各种查询

不难看出,各种查询的底层就是基于过滤来实现的,所以我们可以一句过滤的操作来实现我们的各种查询需求。

总结

经过了这两天的搜索引擎框架的学习,基本上我们可以开发出适合自己项目需求的站内搜索或者全文搜索了。至此,本系列学习也到此结束。

如果我的这些文章恰好给对此迷茫的你一点灵光,我就非常的欣慰了。

:-)

目录
相关文章
|
6月前
|
算法 UED 索引
如何优化因为高亮造成的大文本(大字段)检索缓慢问题
如何优化因为高亮造成的大文本(大字段)检索缓慢问题
136 0
|
JavaScript 前端开发 Java
64jqGrid - 在搜索中显示查询条件
64jqGrid - 在搜索中显示查询条件
57 0
|
自然语言处理 索引
ES 匹配多个搜索条件和精确查询
ES 匹配多个搜索条件和精确查询
|
4月前
|
搜索推荐 UED Python
动态多条件查询:理解`filter_by`与`filter`提升Web应用搜索功能
通过深入理解filter_by与filter的异同,并结合使用它们,我们可以构建一个既灵活又强大的动态多条件查询系统。这不仅提升了Web应用的搜索功能,也为用户提供了更加个性化的搜索体验。希望本文能够启发你在自己项目中实现类似的功能,以满足用户多变的搜索需求。
|
5月前
分享JavaWeb中filter过滤器的案例妙用 - 脏话过滤/编码过滤/代码过滤
分享JavaWeb中filter过滤器的案例妙用 - 脏话过滤/编码过滤/代码过滤
39 0
|
6月前
|
JavaScript
filter来实现模糊搜索的功能-很有用!
filter来实现模糊搜索的功能-很有用!
|
SQL 索引
白话Elasticsearch03- 结构化搜索之基于bool组合多个filter条件来搜索数据
白话Elasticsearch03- 结构化搜索之基于bool组合多个filter条件来搜索数据
301 0
|
JavaScript 前端开发 API
全文检索与高亮关键词匹配,用replace就够了
全文关键词检索高亮,这个在业务中常有的功能,比如浏览器默认就有个功能,关键词搜索就会匹配你检索的文字,并且会给你高亮,这是怎么实现的呢?
308 0
全文检索与高亮关键词匹配,用replace就够了
|
JavaScript Java
DataTables单纯的分页 不排序 没有默认搜索
憋了好几天看了中文和英文的文档,终于把分页搞出来了,先前一直纠结这个页码和页容量怎么传的,其实不用纠结这个,会自动识别。
257 0
|
自然语言处理 搜索推荐
内容搜索排序表达式的最佳实践
本文重点介绍&quot;开放搜索&quot;中的排序表达式的配置及特征性函数的应用
5221 0
内容搜索排序表达式的最佳实践