你好,游客 登录 注册 搜索
背景:
阅读新闻

初识Lucene 4.5全文搜索

[日期:2014-07-22] 来源:Linux社区  作者:linhongyu [字体: ]

以下代码把lucene基本操作方法封装在了IndexUtil类中,其中考虑到创建indexReader开销过大,就设计了单实例模式。注释中会穿插些4.x版本与3.x版本的不同之处。


package lucene;

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

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;

import org.apache.lucene.document.StringField;

import org.apache.lucene.document.TextField;

import org.apache.lucene.document.Field.Store;

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.Term;

import org.apache.lucene.index.IndexWriterConfig.OpenMode;

import org.apache.lucene.queryparser.classic.ParseException;

import org.apache.lucene.queryparser.classic.QueryParser;

import org.apache.lucene.search.IndexSearcher;

import org.apache.lucene.search.Query;

import org.apache.lucene.search.ScoreDoc;

import org.apache.lucene.search.TopDocs;

import org.apache.lucene.store.Directory;

import org.apache.lucene.store.FSDirectory;

import org.apache.lucene.util.Version;

import pojo.LuceneBeans;

public class IndexUtil {

private static Directory directory = null;

private static IndexReader reader = null;

/**

* 设置存储路径

* @return

*/

public static String getIndexDir(){

//得到.class文件所在路径

String classpath = LuceneUtil.class.getResource("/").getPath();

//将class中的%20替换成为空格

classpath = classpath.replaceAll("%20", " ");

//索引存储位置:WEB-INF/classes/index

String path = classpath+"index/";

return path;

}

public IndexUtil(){

try {

//存储方式有CompoundFileDirectory, FileSwitchDirectory, FSDirectory,

//NRTCachingDirectory, RAMDirectory……等分别对应的不同方式

//用FSDirectory的好处就在于它会自动帮你分配该使用哪种方式

directory = FSDirectory.open(new File(getIndexDir()));

//3.x是reader=IndexReader.open(directory);

//但4.x后已经不建议使用,改成了DirectoryReader.open(directory)

reader = DirectoryReader.open(directory);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 创建IndexWriter

* @return

*/

public static IndexWriter getIndexWriter(){

//创建分词器,分词器可根据自己需求去自定义创建,此处以lucene自带的标准分词器分词

Analyzer analyzer=new StandardAnalyzer(Version.LUCENE_45);

IndexWriter indexWriter = null;

try {

IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_45, analyzer);

iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);

indexWriter = new IndexWriter(directory, iwConfig);

return indexWriter;

} catch (IOException e) {

e.printStackTrace();

return null;

}

}

//--------省略余下方法代码

嗯~创建索引前我们需要先获得IndexWriter,其实步骤就像你往数据库中插入一条数据(document),得再这条数据中加入字段(Field),得给这个字段做个说明(Store、Index)……


/**

* 批量创建索引

* @param list

* @return

*/

public boolean createIndexList(List<LuceneBeans> list){

boolean result = false;

IndexWriter indexWriter = IndexUtil.getIndexWriter();

try {

if(list!=null&&list.size()>0){

Document doc = null;

for(int i=0;i<list.size();i++){

doc = new Document();

LuceneBeans lb = list.get(i);

doc.add(new StringField("id",lb.getId(),Store.YES));

doc.add(new TextField("title",lb.getTitle(),Store.YES));

doc.add(new TextField("introduce",lb.getIntroduce(),Store.YES));

doc.add(new StringField("addtime",lb.getAddtime(),Store.YES));

doc.add(new StringField("category",lb.getCategory(),Store.YES));

indexWriter.addDocument(doc);

indexWriter.commit();

result = true;

}

}

} catch (IOException e) {

e.printStackTrace();

}finally{

if(indexWriter!=null){

try {

indexWriter.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

return result;

}

之前3.x版本是这样写的:

doc.add(new Field("id",lb.getI(),Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));

那我们就顺便来分析下store、index

(存储域选项)Store判断是否把域存入文件(yes存入,可还原;no不存入,不可还原但可被索引)

(索引域选项)Index:

//|----ANALYZED进行分词和索引,适用于标题、内容等

//|----NO_ANALYZED进行索引但是不进行分词,身份号、姓名、ID等,适用于精确搜索

//|----ANALYZED_NOT_NORMS进行分词但不存储norms信息,这个norms中包括了创建索引的时间和权值等信息

//|----NOT_ANALYZED_NOT_NORMS既不进行分词也不存储norms信息

但4.x之后就改变了,它需要更为精确的StringField、TextField、IntField……

初识Lucene 4.5全文搜索

那为什么4.x版本只写了Store而没Index?还是让我们看看官方文档上的描述吧:

先看TxetField:自动分词

初识Lucene 4.5全文搜索

再看看StringField:不分词

初识Lucene 4.5全文搜索

所以,4.x有很多写法是与3.x不同的,虽然还可以向下兼容,但总是要跟着时代的脚步前进嘛!

linux
相关资讯       Lucene  Lucene 4.5  Lucene全文搜索 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款