背景
公司的网站需要加一个im,选择环信im进行开发(不要问为什么,免费。),进过一段时间后把流程跑通后,发现对于客户的聊天记录的保存让人比较头疼,经过思考后决定用全文检索做。
开发
开发过程中发现网上基本都是3.X或者4.X的版本,然后其中一些属性4不兼容3,5不兼容4,做的时候各种碰坑,于是想把自己的这个在原大神的代码上做下修改,写了一个5.X的小例子,希望对大家有帮助。
实体
public class User {
private Integer id;
private String name;
private int age;
private String sex;
private Date birthday;
public User(Integer id, String name, int age, String sex, Date birthday) {
super();
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
this.birthday = birthday;
}
//get/set方法,这里省略
}
数据
public class DataUtil {
/**
* 检索资源数据的准备;
* 这里的数据可以来源数据库、文件系统等
* @return
*/
public static List<User> getUsers(){
List<User> list =new ArrayList<User>();
User user =new User(1,"张三1",21,"man",new Date());
list.add(user);
user =new User(2,"张三2",22,"man",new Date());
list.add(user);
user =new User(3,"张三3",23,"woman",new Date());
list.add(user);
user =new User(4,"张三4",24,"man",new Date());
list.add(user);
user =new User(5,"张三5",25,"man",new Date());
list.add(user);
user =new User(6,"张三6",26,"woman",new Date());
list.add(user);
return list;
}
}
主要方法
在方法中有许多属性版本不兼容,于是直接写在注释里面了。
public class IndexWriterDemo {
//存放索引文件的位置,即索引库
static String indexpath = "D:/mylucene/luceneIndex";
//词法分析器
static Analyzer analyzer = new StandardAnalyzer();
/**
* 将即将检索的资源写入索引库
* @param writer
* @throws Exception
*/
public void buildDocs(List<User> list) throws Exception {
///本地文件存储
Directory directory=FSDirectory.open(Paths.get(indexpath));
//内存存储:优点速度快,缺点程序退出数据就没了,所以记得程序退出时保存索引库,与FSDirectory结合使用
//由于此处只暂时保存在内存中,程序退出时没进行索引库保存,因此在搜索时程序会报错
//Directory directory=new RAMDirectory();
//IndexWriterConfig,据官方文档介绍,是对indexWriter的配置,其中包含了两个参数,第一个是目前的版本,第二个是词法分析器Analyzer。最新5.0已经不需要版本号,3.x和4.x需要!
IndexWriterConfig config = new IndexWriterConfig(analyzer);
IndexWriter writer = new IndexWriter(directory,config);
//writer.deleteAll();
//得到数据资源
//List<User> list = DataUtil.getUsers();
System.out.println("buildDocs()->总人数为 :"+list.size());
//存放数据
for(User user :list){
//Document存放经过组织后的数据源,只有转换为Document对象才可以被索引和搜索到
Document doc = new Document();//创建索引库的文档
doc.add(new TextField("id",String.valueOf(user.getId()),Store.YES));
doc.add(new TextField("name",user.getName(),Store.YES));
doc.add(new TextField("age",String.valueOf(user.getAge()),Store.YES));
doc.add(new TextField("sex",user.getSex(),Store.YES));
doc.add(new TextField("birthday",String.valueOf(user.getBirthday()),Store.YES));
//将文档写入索引库
writer.addDocument(doc);
}
int count =writer.numDocs();
//关闭IndexWriter,提交创建内容
writer.close();
System.out.println("buildDocs()->存入索引库的数量:"+count);
}
/**
* 清空索引
* @throws IOException
*
*/
public void delDocs() throws IOException{
Directory directory=FSDirectory.open(Paths.get(indexpath));
IndexWriterConfig config = new IndexWriterConfig(analyzer);
IndexWriter writer = new IndexWriter(directory,config);
//清空索引库里已存在的文档(document)
writer.deleteAll();
writer.close();
}
/**
* 从索引库中搜索你要查询的数据
* @param searcher
* @throws IOException
*/
public void searcherDocs() throws IOException{
Directory directory=FSDirectory.open(Paths.get(indexpath));
IndexReader reader = DirectoryReader.open(directory);
IndexSearcher searcher =new IndexSearcher(reader);
List articleList = new ArrayList();
// 创建一个排序对象,其中SortField构造方法中,第一个是排序的字段,第二个是指定字段的类型,第三个是是否升序排列,true:升序,false:降序。
// Sort sort = new Sort(new SortField("age", Type.STRING, false));
//sort = Sort.INDEXORDER;// 评分降序排列
Sort sort = new Sort();
sort.setSort(new SortField("id",SortField.Type.DOC,true));//true为降序,false为升序
Term term =new Term("sex", "man");//查询条件,意思是我要查找性别为“man”的人
TermQuery query =new TermQuery(term);
//TopDocs docs = searcher.search(new TermQuery(new Term("sex", "man")), null, 100, sort, true, true);
//TopDocs topDocs = indexSearcher.search(query, 5, sort);
TopDocs docs =searcher.search(query, 3, sort);//查找
System.out.println("searcherDoc()->男生人数:"+docs.totalHits);
for(ScoreDoc doc:docs.scoreDocs){//获取查找的文档的属性数据
int docID=doc.doc;
Document document =searcher.doc(docID);
String str="ID:"+document.get("id")+",姓名:"+document.get("name")+",性别:"+document.get("sex");
System.out.println("人员信息:"+str);
}
}
}
调用
public static void main(String[] args) throws Exception {
IndexWriterDemo demo =new IndexWriterDemo();
//获取数据
List<User> list = DataUtil.getUsers();
/**生成索引库*/
demo.buildDocs(list);
/**查询数据*/
demo.searcherDocs();
demo.delDocs();
}
参考:
- Lucene搜索方式大合集 :http://blog.csdn.net/u012443091/article/details/43941241
- lucene操作索引的几个常用方法:http://www.656463.com/article/rqyeim.htm