Compass: 在你的应用中集成搜索功能

2024-06-09 15:32

本文主要是介绍Compass: 在你的应用中集成搜索功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文转载自:http://www.infoq.com/cn/articles/compass-search-tutorial

驱动力

在许多应用程序中,用户总会提出搜索和查询领域实例的需求。他们或者希望构建一个进入应用程序的入口或者希望填充表单的机制。非常典型的解决方案是用浏览的方式(把领域的继承关系表现出来,这样用户可以定位和选择一个自己需要的)或者一个检索表单的方式(展现一个多个输入域的表单,用户可以检索他们需要的信息)。

现实中,对于可用性的角度来说,这两种方案都不是最佳的。浏览的方式会在有许多分支的时候变得缓慢而笨重。而且,用户通常精确地知道他们要用到那个应用,然而却不情愿要浏览整个系统来找到他要的应用。检索表单的方式同样被检索条件个数的多少限制住了。这就要在设置足够的检索域还是检索表单的复杂性上作出权衡。

从可用性的角度来说,解决这个问题的答案就是提供一个单一的、Google样式的检索框,用户可以输入任何符合实例字段的内容。他们可以检索和表示符合这些内容的结果。表单中的这个检索框可以自动填充、Google建议模式的输入框,或者是返回表格式结果的正则表达式搜索。不管怎样,这种解决方案的精髓就是UI是简单的,用户可以输入任何他们选择的条件,然后由搜索引擎去做这些复杂的工作。现在唯一的问题时:如何实现这样的搜索机能。

当面对实现传统的多输入域的表单的时候,大部分应用程序都选择了SQL。典型的情况是,检索的字段都与列名相匹配,并且使用SQL的LIKE语句。然而,因为复杂的SQL要去匹配太多的字段,并且很多情况下由于这些字段的文本长度问题,造成实现的性能经常是非常差的。第二个问题是,对检索结果没有排名并且返回的提示并没有反应出与查询的内容有多大相关性,只是简单地返回结果罢了。第三,对检索结果相关联的关键字没有高亮表示。

很快,大家意识到大部分应用程序需要搜索引擎。所有实体的字段可以像只有一个文件那样被索引,并且是正则文本搜索可以匹配的实体。现在非常流行的搜索引擎之一是Luence。Lucene是相当不错的搜索引擎,在很多项目中应用成功。它提供了底层的搜索引擎API,能够使用Lucene数据结构(Document/Field)去索引数据,能供使用查询API或搜索引擎在索引上检索。它已经在多种编程语言上实现了全部功能,包括Java、C#和C++等。

如果我们分析一个典型的Web应用程序,一般都有个一个共通的架构和特点。通常,应用与后端的关系数据库一起工作。这个应用使用领域模型表示这个系统中的实体,并使用ORM框架把领域模型映射到数据库上。一般情况下,使用一个服务层框架去管理事务、协作,有时也包括业务逻辑和Web框架。问题就在于怎么把Lucene集成到这样的应用程序中去。

当你试图去集成Lucene的时候,刚刚把第一个简单的程序跑起来的时候,马上就会遇到一连串的挑战。第一个问题就是索引应用数据。在之前很长一段时间,相当多的样板式代码热衷于把领域模型映射到Lucene数据模型上去。Lucene文档,是Lucene主要的数据结构,它是一个扁平的类似Map的,只包含字符串的数据结构——所以许多无意义的代码热衷于“植入”和“植出”领域模型。另外一个问题是缺少对Lucene的事务控制,把领域模型数据存储到数据库和搜索引擎是有问题的。而且还有几个其他的很有名的实践和模式要在Lucene中实现,比如缓存、隐式的搜索、为支持Google样式的搜索而创建聚集的属性和为合适的语义保持可识别的Document对象,等等。

Compass简介

Compass的设计目标是简化企业在集成搜索功能时的花费。Compass是在Lucene之上,使用了设计很好的搜索引擎的抽象。Compass扩展了核心Lucene,增加了事务控制功能和快速更新,也包括在数据库存储索引的功能。当然,它没有去隐藏Lucene的特性——所有Lucene的功能都能通过Compass实现。

Compass核心API

Compass提供给了我们简单的并且熟悉的API。说Compass提供了让人熟悉的API是因为它模仿了当前流行的ORM框架的API来降低学习曲线。Compass以下面一些主要的接口作为主要内容:

  • CompassConfiguration:用来在一些设置参数、配置文件和映射定义上配置Compass。通常用来创建Compass接口。
  • Compass:为单线程使用,创建线程安全的实例来打开Compass Seesion。同样还提供了一些搜索引擎索引级别的操作。
  • CompassSesssion:用来执行像保存、删除、查找、装载这样的搜索操作。很轻量但是并不是线程安全的。
  • CompassTransaction:管理Compass事务的接口。使用它并不需要事务管理环境(像Spring、JTA)。

下面是使用这些API的一个简单的例子:

// 在程序中配置和创建Compass
CompassConfiguration conf =
new CompassConfiguration().setConnection("/tmp/index").addClass(Author.class);
Compass compass = conf.buildCompass();

// 一个请求操作
CompassSession session = compass.openSession();
CompassTransaction tx = null;
try {
tx = session.beginTransaction();
...
session.save(author);
CompassHits hits = session.find("jack london");
Author a = (Author) hits.data(0);
Resource r = hits.resource(0);
...
tx.commit();
} catch (CompassException ce) {
if (tx != null) tx.rollback();
} finally {
session.close();
}

为了简化事务管理代码,Compass提供了好几种选择,首先是使用CompassTemplate,它使用流行的设计模式来抽象事务管理。第二个选择是在和事务管理环境下,这样,Compass与JTA与Spring这样的事务管理器集成并在一个已经存在的事务中执行。这个情况下,当一个Session执行的时候,CompassSession 可被用做一个自动加入事务处理的代理。这个代理的创建可以是编程式的,也可使用Spring IOC(Spring 2 中支持@CompassContext)。

Compass支持原子性的事务运算,与不同的事务管理策略集成,包括本地事务管理、JTA同步、XA for JTA的集成,Spring同步的集成。

Compass的配置基于“键—值”的一一对应的设置。Compass可以使用编程式的配置,基于XML DTD的配置(定义映射和设置),基于XML Schema的配置。基于XML Schema的配置得到了Spring2新的基于Schema配置文件的支持。

搜索引擎映射

Compass的主要功能之一就是从应用程序模型到搜索引擎的声明式映射。Compass搜索引擎的领域模型由资源(Lucene Document)和属性(一个Lucene Field)组成。这是用来索引可搜索内容的抽象数据对象。

RSEM

第一个映射是RSEM(Resource/SearchEngine Mapping)。这是一个低级别从Compass资源和属性到搜索引擎抽象到搜索引擎的映射。下面是个对作者资源的RSEM的示例:

<resource alias="author">
<resource-id name="id"/>
<resource-property name="firstName"/>
<resource-property name="lastName" store="yes" index="tokenized"/>
<resource-property name="birthdate" converter="mydate"/>
</resource>

上面的例子中,我们定义了一个映射了作者别名的资源。这个资源的映射包括标识资源的ID和几个附加的属性。定义属性是可选的,尽管他们允许声明式的控制不同属性的特征,包括和一个转换器关联。下面的示例代码填充了一个资源并索引它。

Resource r = session.createResource("author");
r.addProperty("id", "1")
.addProperty("firstName", "jack")
.addProperty("lastName", "london")
.addProperty("birthdate", new Date());
session.save(r);

上面的代码显示了一些Compass的特性。第一,由于一个资源是可识别的,Compass在这个资源已经存在的情况下更新它。第二,可以声明式的分配一个转换器给这个资源,可以使用Compass内置的许多转换器。下面是上面示例代码的Compass配置(包括对mydate转换器的配置):

<compass-core-config xmlns="http://www.opensymphony.com/compass/schema/core-config" 
xsi:schemaLocation="http://www.opensymphony.com/compass/schema/core-config
http://www.opensymphony.com/compass/schema/compass-core-config.xsd">
<compass name="default">
<connection>
<file path="index" />
</connection>
<converters>
<converter name="mydate" type="org.compass.core.converter.basic.DateConverter">
<setting name="format" value="yyyy-MM-dd" />
</converter>
</converters>
<mappings>
<resource location="sample/author.cpm.xml" />
</mappings>
</compass>
</compass-core-config>

OSEM

OSEM(Object/Search Engine Mapping)是第二个支持的映射方案。它允许把应用对象的领域模型映射到搜索引擎。下面是Author类,使用注释对它进行了OSEM定义:

@Searchable
public class Author {

@SearchableId
private Long id;

@SearchableComponent
private String Name;

@SearchableReference
private List books;

@SearchableProperty(format = "yyyy-MM-dd")
private Date birthdate;
}

// ...

@Searchable
public class Name {

@SearchableProperty
private String firstName;

@SearchableProperty
private String lastName;
}

OSEM支持“植入”和“植出”一个对象的分层结构进入一个资源。当存储一个Author对象,Compass就会“植入”进一个资源,Name类也会“植入”进相同的资源来表示这个作者(由于组件的映射),也包括一个这个作者书籍列表里的每一本书(存储在其他的资源里)的引用。这个最后得到的资源会存储或者索引在搜索引擎中。

Compass提供了非常灵活的机制来把领域模型映射到搜索引擎中。上面的例子只是一个很简单的例子。OSEM允许制定不同的转换器,一个类属性对应多个元数据(从资源到属性的映射)、分析器和所有参与的字段,等等。

下面是author类怎样使用的例子:

// ...
Author author = new Author(1, new Name("jack", "london"), new Date());
session.save(author);
// ...
author = (Author) session.load(Author.class, 1);

XSEM

最后,Compass支持的搜索引擎映射是XSEM(Xml/Search Engine Mapping)。这种映射允许基于XML映射的定义(用XPath实现),把XML数据结构直接映射到搜索引擎。XSEM的处理同样的通过对资源“植入”和“植出”的处理。Compass提供了一个XML包装对象叫做XmlObject,它定义了不同的实现(dom4j, W3C Document),这些实现允许XPath表达式来求值。如果我们给出下面的XML数据结构:

<xml-fragment>
<author id="1">
<firstName>Jack</firstName>
<lastName>London</lastName>
</author>
</xml-fragment>

下面是个XSEM的实现:

<compass-core-mapping>
<xml-object alias="author" xpath="/xml-fragment/author">
<xml-id name="id" xpath="@id" />
<xml-property xpath="firstName" />
<xml-property xpath="lastName" />
<xml-content name="content" />
</xml-object>
</compass-core-mapping>

从XML数据结构到搜索引擎的映射是使用XPath表达式来完成。XML内容映射可以在搜索引擎中存储为XML结构,这样就可以加载和搜索数据。Compass支持多种XML DOM框架(为XML内容作映射),包括JSE5, dom4j(SAX 和XPP),当然定制的实现也很好做。下面是个不错的例子:

Reader reader = // construct an xml reader over raw xml content
AliasedXmlObject xmlObj = RawAliasedXmlObject("author", reader);
session.save(xmlObj);
// ...
Resource resource = session.loadResource("author", 1);
// since we have xml-content, we can do the following as well
XmlObject xmlObj = session.load("author", 1);

Compass Gps

Compass Gps 是Compass的一个组件,用来把不同的数据源与Compass集成。大部分常用的数据源是Compass与ORM工具的集成。Compass支持JPA、Hibernate、OJB、JDO和iBatis。

拿Hibernate作为例子,Compass给出了两个主要的操作:索引与镜像。拥有这两个映射的对象可以通过使用Hibernate API注册时间监听,进行自动的镜像操作到搜索引擎。下面的例子给出了怎样使用Compass Gps集成Hibernate:

SessionFactory sessionFactory = // Hibernate Session Factory
Compass compass = // set up a Compass instance
CompassGps gps = new SingleCompassGps(compass);
CompassGpsDevice device = new Hibernate3GpsDevice("hibernate", sessionFactory);
gps.addDevice(device);
// start the gps, mirroring any changes made through Hibernate API
// to be mirrored to the search engine
gps.start();

// ....

// this will cause the database to be indexed
gps.index();
// this will cause Hibernate to store the author in the database
// and also index the author object through Compass
hibernateSess.save(new Author(1, new Name("jack", "london"), new Date()));

总结

这篇文章对Compass的主要功能的做了介绍,但只是覆盖了怎样使用Compass的基本功能(尤其,Compass还有个与Spring集成的扩展组件,这个并没介绍)。在使用搜索引擎的时候,Compass同样也有很多现在流行功能和有一些细微的差别功能,还有配置扩展功能。Compass的主要目标,像刚才提到的,是简化集成搜索到任何类型的应用程序中,这篇文章只是介绍了怎么使用的基本信息。

关于作者

Shay是Compass开源项目的建立者,Compass是唯一集成搜索功能到各种应用模型中的解决方案。他先是专注于实时的C/C++系统,后来转到Java开发(不再回头)。在Java世界中, Shay最近在实现分布式规则引擎服务器的工作。这是一个典型的Java为基础的Web项目,面向金融行业、以消息为基础的项目。现在Shay是GigaSpaces的系统架构师。

查看英文原文: Compass: Integrate Search into your apps
译者简介:  周刚,毕业于北京邮电大学应用数学专业,现就职于BULL。目前主要关注以Spring Framework和JPA为主干的JavaEE和JavaFX技术,重视对JavaSE基础的知识的传播,尽已所能参与技术社区的内容建设工作,以期共同提高技术水平。参与InfoQ中文站内容建设,请邮件至 china-editorial@infoq.com ,加入InfoQ中文站用户讨论组,请点击 ICUG,InfoQ China User Group

这篇关于Compass: 在你的应用中集成搜索功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045570

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、