Lucene使用实例

来源:互联网 发布:算法爱好者 公众号 编辑:程序博客网 时间:2024/06/06 16:36

Lucene全文检索大体分两个部分:索引创建(Indexing)和搜索索引(Search)

1. 索引过程
1) 有一系列被索引文件(此处所指即文本数据)
2) 被索引文件经过语法分析和语言处理形成一系列词(Term)。
3) 经过索引创建形成词典和反向索引表。
4) 通过索引存储将索引写入硬盘。
2. 搜索过程
1) 用户输入查询语句。
2) 对查询语句经过语法分析和语言分析得到一系列词(Term)。
3) 通过语法分析得到一个查询树。
4) 通过索引存储将索引读入到内存。
5) 利用查询树搜索索引,从而得到每个词(Term)的文档链表,对文档链表进行交,差,并得到结果文档。
6) 将搜索到的结果文档对查询的相关性进行排序。
7) 返回查询结果给用户。

Lucene目前版本5.2.1,下面我们以这个版本演示一下Lucene的使用代码。

下面我们以一个实例说明:

引入依赖包:

<properties><lucene.version>5.2.1</lucene.version></properties><dependencies><dependency><groupId> org.apache.lucene</groupId><artifactId> lucene-core</artifactId><version> ${lucene.version}</version></dependency><dependency><groupId> org.apache.lucene</groupId><artifactId> lucene-analyzers-common</artifactId><version> ${lucene.version}</version></dependency><dependency><groupId> org.apache.lucene</groupId><artifactId> lucene-queryparser</artifactId><version> ${lucene.version}</version></dependency></dependencies>
实例对象:

package cn.slimsmart.lucene.demo.example;import java.util.ArrayList;import java.util.List;public class User {private String id;private String name;private String desc;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public static List<User> getInitList(){List<User> list = new ArrayList<User>();User user = new User();user.setId("10001");user.setName("张三");user.setDesc("张三是个农民,勤劳致富,奔小康");list.add(user);user = new User();user.setId("20001");user.setName("李四");user.setDesc("李四是个企业家,白手起家,致富一方");list.add(user);user = new User();user.setId("11111");user.setName("王五");user.setDesc("王五好吃懒做,溜须拍马,跟着李四,也过着小康的日子");list.add(user);return list;}}
使用实例:

package cn.slimsmart.lucene.demo.example;import java.io.File;import java.nio.file.Paths;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field.Store;import org.apache.lucene.document.StringField;import org.apache.lucene.index.DirectoryReader;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.index.IndexWriterConfig.OpenMode;import org.apache.lucene.index.Term;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TermQuery;import org.apache.lucene.search.TopDocs;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;public class Test {public static void main(String[] args) throws Exception {createIndex();search();}public static void createIndex() throws Exception {String pathFile = new File("src/main/resources").getAbsolutePath();// 索引文件的保存位置Directory dir = FSDirectory.open(Paths.get(pathFile));// 分析器Analyzer analyzer = new StandardAnalyzer();// 配置类IndexWriterConfig iwc = new IndexWriterConfig(analyzer);/** APPEND:总是追加,可能会导致错误,索引还会重复,导致返回多次结果 CREATE:清空重建(推荐) CREATE_OR_APPEND【默认】:创建或追加 */iwc.setOpenMode(OpenMode.CREATE);// 创建模式 OpenMode.CREATE_OR_APPEND 添加模式IndexWriter writer =  new IndexWriter(dir, iwc);for (User u : User.getInitList()) {Document doc = new Document();doc.add(new StringField("id", u.getId(), Store.YES));doc.add(new StringField("name",u.getName(), Store.YES));doc.add(new StringField("desc", u.getDesc(), Store.YES));System.out.println(doc);writer.addDocument(doc);}System.out.println("初始化完毕");writer.commit();writer.close();}public static void search() throws Exception {  String pathFile = new File("src/main/resources").getAbsolutePath();Directory dir = FSDirectory.open(Paths.get(pathFile));IndexReader reader=DirectoryReader.open(dir);          IndexSearcher searcher=new IndexSearcher(reader);          //对于中文查询,需要分词        Term term=new Term("name", "张三");         Query query= new TermQuery(term);          //模糊搜索        //Term term=new Term("desc", "*小康*");         //Query query= new WildcardQuery(term);          //n 查找top        TopDocs topdocs=searcher.search(query, 2);          ScoreDoc[] scoreDocs=topdocs.scoreDocs;          System.out.println("查询结果总数:" + topdocs.totalHits);          System.out.println("最大的评分:"+topdocs.getMaxScore());          for(int i=0; i < scoreDocs.length; i++) {              int doc = scoreDocs[i].doc;              Document document = searcher.doc(doc);              System.out.println("docid:" + scoreDocs[i].doc);            System.out.println("scors:" + scoreDocs[i].score);            System.out.println("shardIndex:" + scoreDocs[i].shardIndex);            System.out.println("id:"+document.get("id")+",name:"+document.get("name")+",desc:"+document.get("desc"));          }          reader.close();  }}
运行可以看到:

初始化完毕查询结果总数:1最大的评分:1.4054651docid:0scors:1.4054651shardIndex:0id:10001,name:张三,desc:张三是个农民,勤劳致富,奔小康

注:由于lucene自带的分词方式对中文分词十分的不友好,所以在对一段中文中的某个词组进行搜索时,需要在创建索引是对其进行分词,如搜索desc中的“致富”,无法获取结果。

参考文章:

1.Lucene:基于Java的全文检索引擎简介

2.Lucene原理与代码分析

0 0
原创粉丝点击