Lucene是Java领域最出色的全文搜索引擎,然而其API比较复杂,并且有严格的线程同步模型,直接使用不易。Compass则是封装了Lucene的一个OSEM:Object-SearchEngine Mapping,与Hibernate封装JDBC类似,然而过于复杂,支持的Lucene版本较低,在www.javaeedev.com发现雪峰开发一个类似Compass的简单封装Lucene的全文搜索框架,支持最新版本Lucene和Java 5泛型代码,用户通过简单的代码即可对自定义Bean进行搜索:
List<T> list = Searcher.search(Class<T>, String q, Page page);
下载地址:
http://code.google.com/p/lightweight-search/downloads/list
下面介绍下简单的用法:
1.自定义Bean,例如:Article
import com.javaeedev.lightweight.search.Index;
import com.javaeedev.lightweight.search.SearchableId;
import com.javaeedev.lightweight.search.SearchableProperty;
import com.javaeedev.lightweight.search.Store;
/**
* Article bean that can be searched.
*
* @author Xuefeng
*/
public class Article {
private String id;
private String title;
private String author;
private String content;
@SearchableId
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@SearchableProperty(store=Store.YES, index=Index.TOKENIZED, boost=3.0f)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@SearchableProperty(store=Store.YES, index=Index.TOKENIZED, boost=2.0f)
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@SearchableProperty(store=Store.YES, index=Index.TOKENIZED)
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
其中特别的地方就是@SearchableId和@SearchableProperty
@SearchableId是描述lucene索引的ID
@SearchableProperty是描述lucene索引域的
以上二属性的详细信息请查询lucene,应为此框架的原理仅仅是对lucene的封装。
2.实现全文全文搜索
有两种方法:
一 直接用行,所需参数在调用类中配置,例如:
import com.javaeedev.lightweight.common.Page;
import com.javaeedev.lightweight.search.Searcher;
import com.javaeedev.lightweight.search.SearcherProvider;
/**
* Run directly.
*
*/
public class Run {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// define classes that can be searched:
Set<Class> searchableClasses = new HashSet<Class>();
searchableClasses.add(Article.class);
// init a provider:
SearcherProvider provider = new SearcherProvider("./index-location", searchableClasses);
provider.setAnalyzer(new StandardAnalyzer());
provider.setHighlightPre("<b>");
provider.setHighlightPost("</b>");
// get a searcher:
Searcher searcher = provider.get();
// now do all search work with "searcher" object:
// first add new Articles:
Article a = new Article();
a.setId(UUID.randomUUID().toString());
a.setTitle("How to use lightweight search?");
a.setAuthor("Liao Xuefeng");
a.setContent("Lightweight search project is an open source project that using Lucene but simplify full text search.");
searcher.index(a);
// now search:
Page page = new Page(1);
List<Article> articles = searcher.search(Article.class, "lightweight", page);
System.out.println("Results: " + page.getTotalCount());
for(Article article : articles) {
System.out.println(article.getTitle() + " by " + article.getAuthor());
}
}
}
(注意:请注意其代码中的注释部分)
二 借助于Guice注入(相关Guice的资料)
借助于Guice注入,首先要做的就是初始化Guice
import com.google.inject.Module;
import com.google.inject.name.Names;
import com.javaeedev.lightweight.search.Searcher;
import com.javaeedev.lightweight.search.SearcherProvider;
/**
* Init Google Guice IoC Container.
*
*/
public class MyModule implements Module {
@SuppressWarnings("unchecked")
public void configure(Binder binder) {
binder.bindConstant().annotatedWith(Names.named("HighlightPre")).to("<span class=\"highlight\">");
binder.bindConstant().annotatedWith(Names.named("HighlightPost")).to("</span>");
binder.bindConstant().annotatedWith(Names.named("IndexLocation")).to("./index-location");
Set<Class> set = new HashSet<Class>();
set.add(Article.class);
binder.bind(new Key<Set<Class>>(Names.named("SearchableClasses")) {}).toInstance(set);
binder.bind(Analyzer.class).to(StandardAnalyzer.class).asEagerSingleton();
binder.bind(Searcher.class).toProvider(SearcherProvider.class).asEagerSingleton();
}
}
其次创建调用
import java.util.List;
import java.util.UUID;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.javaeedev.lightweight.common.Page;
import com.javaeedev.lightweight.search.Searcher;
/**
* Run demo with Google Guice as IoC container.
*
* @author Xuefeng
*/
public class RunWithGuice {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MyModule());
Searcher searcher = injector.getInstance(Searcher.class);
// now do all search work with "searcher" object:
// first add new Articles:
Article a = new Article();
a.setId(UUID.randomUUID().toString());
a.setTitle("How to use lightweight search?");
a.setAuthor("Liao Xuefeng");
a.setContent("Lightweight search project is an open source project that using Lucene but simplify full text search.");
searcher.index(a);
// now search:
Page page = new Page(1);
List<Article> articles = searcher.search(Article.class, "lightweight", page);
System.out.println("Results: " + page.getTotalCount());
for(Article article : articles) {
System.out.println(article.getTitle() + " by " + article.getAuthor());
}
}