首页 > 代码库 > 3.Lucene3.x API分析,Director 索引操作目录,Document,分词器
3.Lucene3.x API分析,Director 索引操作目录,Document,分词器
1 Lucene卡发包结构分析
包名 | 功能 |
org.apache.lucene.analysis | Analysis提供自带的各种Analyzer |
org.apache.lucene.collation | 包含collationKeyFilter和collationKeyAnalyzer两个相同功能的类,将所有token转为CollationKey,与IndexableBinaryStringTools一起存为term |
org.apache.lucene.document | Document包中是Document相关各种数据结构,如Document类,Field类等 |
org.apache.lucene.index | index包中是索引的读写操作类,常用的是对索引文件的segment进行写、合并和优化的IndexWriter类和对索引进行读取和删除操作的IndexReader类 |
org.apache.lucene.queryParser | queryParser包中是解析查询语句相关的类(常用的是QueryParser类) |
org.apache.lucene.search | 检索管理,根据查询条件,检索得到结果search包中是从索引中进行搜索的各种不同的Query类(如TermQuery、BooleanQuery等)和搜索结果集Hits类 |
org.apache.lucene.store
| store包中是索引的存储相关类,如Directory类定义了索引文件的存储结构,FSDirectory是存储在文件系统(即磁盘)中的索引存储类,RAMDirectory为存储在内存中的索引存储类 |
org.apache.lucene.util | util包中是公共工具类,例如时间和字符串之间的转换工具 |
2 Director索引操作目录
FSDirectory :磁盘路径,在磁盘中创建文件索引库
RAMDirectory:内存路径,指在内存中创建文件索引库
//当前工程index目录,相对路径 FSDirectory.open(new File("index")); //绝对路径 FSDirectory.open(new File("d:\\index")); //在类路径下创建 FSDirectory.open(new File(LuceneTest.class.getResource("/").getFile()));
//内存路径 RAMDirectorydirectory = new RAMDirectory(); |
3 分词器(主要要完全搜索的不要分词,比如当查询书的书号时不分词)
Analyzer 分词器
new StandardAnalyzer(Version.LUCENE_36); //建立标准分词器,对于汉子采用单自分词
4 Document索引中文对象,Field文档内部数据信息
每个数据对象,对应一个Document对象
对应一个属性,对应一个Field对象
newField(fieldname,value,Store,Index); 将数据建立索引库Field,Store决定是否存储,Index决定是否索引分词
Store.YES存储、Store.NO 不存储 Index.NO 不建立索引 Index.ANALYZED分词建立索引 保存权重信息 Index.NOT_ANALYZED不分词建立索引 Index.ANALYZED_NO_NORMS 分词建立索引,不存放权重信息 Index.NOT_ANALYZED_NO_NORMS不分词建立索引,不存放权重信息 |
Document document =new Document(); document.add(new Field("id", article.getId() +"", Store.YES, Index.NOT_ANALYZED));//对于id通常不分词的 document.add(newField("title",article.getTitle(),Store.YES,Index.ANALYZED)); document.add(new Field("content", article.getContent(), Store.YES,Index.ANALYZED)); |
@Test //查询索引库,查看norms效果 publicvoid testQuery()throws Exception { //建立Query对象--根据标题 String queryString = "Lucene"; //第一个参数,版本号 //第二个参数,字段 //第三个参数,分词器 Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36); QueryParser queryParser = new QueryParser(Version.LUCENE_36,"content", analyzer); Query query = queryParser.parse(queryString);
//根据Query查找 //索引目录位置 Directory directory = FSDirectory.open(new File("index")); IndexSearcher indexSearcher = new IndexSearcher( IndexReader.open(directory)); //查询满足结果的前100条数据 TopDocs topDocs = indexSearcher.search(query, 100); System.out.println("满足结果记录条数:" + topDocs.totalHits);
//获取结果 ScoreDoc[] scoreDocs = topDocs.scoreDocs; for (int i = 0; i < scoreDocs.length; i++) { //先获得Document下标 int docID = scoreDocs[i].doc; Document document = indexSearcher.doc(docID); System.out.println("得分:" + scoreDocs[i].score); System.out.println("id:" + document.get("id")); System.out.println("title:" + document.get("title")); System.out.println("content:" + document.get("content")); }
indexSearcher.close(); } |
运行结果: |
是否分词,根据业务查找条件决定 是否存储,根据业务是否需要返回结果数据决定 norm是按照词频计算的 问题:Index.ANALYZED 和 Index.ANALYZED_NO_NORMS 区别 Index.ANALYZED 会保存权重信息 Index.ANALYZED_NO_NORMS 不会保存权重信息
权重会影响得分,得分计算排名,搜索技术搜索结果一定要进行排序,按照得分 *不保存norm值,默认按照 1.0计算 * norm是按照词条数计算,值<= 1 index.ANALYZED_NO_NORMS效率会高一些 |
4索引创建过程
分词器Analyzer
目录Directory
进入索引写入,必须使用IndexWriter,但是在初始化IndexWriter过程中,对目标索引库加锁。
当试图对一个索引库创建多个IndexWriter时,报异常
org.apache.lucene.util.SetOnce$AlreadySetException:The object cannot be set twice!
*使用同一 indexWriterConfig两次
org.apache.lucene.store.LockObtainFailedException:Lock obtain timed out:NativeFSLock@D:\work\javaee20130408\lucene3_day1\index\write.lock
*试图创建第二个IndexWriter,第一个IndexWriter还没有关闭,锁文件还在
问题:如果两个线程同时对一个索引库操作怎么办?---解决办法:只能使用同一个IndexWriter对象
3.Lucene3.x API分析,Director 索引操作目录,Document,分词器