1

我有一个数字图书馆系统,我在其中存储元数据和数据库中物理文件的路径。文件可以是任何内容:纯文本、Word、PDF、MP3、JPEG、MP4...

如何为我的域对象和物理文件(或文件的某些文本提取)提供全文搜索。

将文档文本存储在域对象中是我唯一的选择吗?无论搜索结果来自域对象还是物理文档,我都需要能够检索域对象列表。当然,使用文件路径可能存在连接,我实际上将每个文档放在由 GUID 命名的文件夹中,所以连接就在那里。

我需要在 Grails 中执行此操作,最好使用 solr 或可搜索插件,但 Java 解决方案会有所帮助。

4

2 回答 2

0

看看这篇文章,它涵盖了像你这样的用例,基于SpringHibernate、Hibernate Search 和 JSF。它带有一个全面的、有据可查的示例应用程序

它专注于关注范式和模块化的分离,顺便说一句。因此,涉及全文搜索的概念应该适合 Grails 或其他基于 Java 的应用程序。

域类de.metagear.library.model.Media(也有一个关联的MetaData域类)。您将能够混合使用 Hibernate 和 GORM 类;但是,您需要使用不同的 API。

该类Media包含一个属性plainText

@Column(name = "plain_text", nullable = false)
@Field(index = Index.TOKENIZED, store = Store.YES)
@Lob
private String plainText;

该属性保存提取的文本(即,来自 PDF 等)。我不确定是否需要将其保存到数据库中(可能不需要,但否则不会造成太大伤害)。然而,它用于全文搜索(见下文)。对于全文搜索,仅使用 Lucene 索引。

Media创建 a 之前,会提取相应原始文档(可能是二进制文档)的文本内容。该de.metagear.library.model.factory.MediaFactory.getInstance(..)方法提取文本,将提取的文本存储在一个新Media对象中,然后返回Media

在示例中,它只是将原始文档存储到域对象的属性中,但是,在该位置,您还可以将文档保存到文件并将引用(您提到的 GUID)存储到Media的属性中。

域类由类保存de.metagear.library.dao.MediaCrudDaoImpl,它是一个 Spring bean。在内部,它使用了一个注入EntityManagerFactory,在/applicationContext.xml 中,它已被定义为在后台使用 Hibernate。

由于域类中的 Hibernate 注释,索引会自动发生。

至于自己进行全文搜索,是通过查询数据库,只查询Lucene索引的de.metagear.library.dao.MediaSearchDaoImpl.getSearchResults(..)方式来完成的。

示例应用程序包含一个强大的查询词预处理器,它可以在不同的索引上组合 AND、OR 和 NOT 运算符,同时保留全面的Lucene 表达式语法

通过在这个地方设置一个自定义org.hibernate.transform.ResultTransformer,可以返回任何类型的对象(当然包括域类)。


我还没有研究过 Grails Searchable 插件,因此无法判断它在健壮性、可维护性、易用性以及自定义或第三方内容提取器的可扩展性方面是否可行、解析器和分析器。可能,它也是。

毕竟,我的方法涉及 Spring 和(也许)Hibernate 框架的基本知识。这些只是 Grails 和 Gorm 所基于的框架,但我认为这可能会为您提供一个决策点。

至少,在查看不同的框架和方法时,查看上述概念应该是有益的,并且能够推进。

谢谢。

于 2010-11-04T21:58:41.817 回答
0

您不需要将内容存储在域对象中,只需在创建索引条目时将内容与域对象关联即可。我使用Apache POI来提取我的内容,但还有更高级别的服务,例如Apache Tika

您可以直接使用Lucene在 java 中对其进行编码,但我建议改为SOLR

基于Lucene的Compassgrails 可搜索插件

于 2010-10-23T15:26:05.393 回答