Jackrabbit是利用Lucene实现的全文检索。具体的实现在jackrabbit-core项目的org.apache.jackrabbit.core.query.lucene包中。
索引过程的关键类有以下几个:
1、org.apache.jackrabbit.core.query.lucene.NodeIndex。这个类的核心方法是createDoc,在这里,生成了Lucene的Document,并且处理了JCR节点的各个属性。在这个类里还可以看到jackrabbit是利用tika处理的binary数据(addBinaryValue方法中),同时也可以看到jackrabbit的一个比较龌龊的实现:对于二进制流,只有放在名称为jcr:data的属性中才会被索引。具体的代码是这个样子的:
String jcrData = mappings.getPrefix(Name.NS_JCR_URI) + ":data";
if (!jcrData.equals(fieldName)) {
// don't know how to index
return;
}
所以,nt:file类型下的文档内容会自动被索引。如果你想自定义类型,并且希望其中的二进制字节数据被索引,那么,你有两个选择:
第一:改jackrabbit的代码,让他支持你的属性;
第二:将放置二进制字节数据的属性名设置为jcr:data,并且让该节点继承nt:resource(需要mimetype等属性)。
当然绝大多数人会选择第二种吧。
2、org.apache.jackrabbit.core.query.lucene.SearchIndex。这个类是jackrabbit与Lucene交互的核心类,索引和检索都是通过它来完成的,具体是executeQuery、updateNodes两个方法。在updateNodes方法中,会利用NodeIndex来建立索引。
3、org.apache.jackrabbit.core.SearchManager。该类实现了SynchronousEventListener接口,换句话说Jackrabbit的索引过程采用的是其自身的Listener机制。其onEvent会调用SearchIndex的updateNodes来更新索引。
综上,jackrabbit利用lucene的索引过程并不复杂。
另外,对于JCR,有个问题是其接口不支持二次检索,希望在JCR的后续版本中能改进。最简单的方法就是在Query中加一个executeWithFilter就是了。