package junit;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.lang.math.NumberUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.NumericRangeFilter;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.search.regex.RegexQuery;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer; import com.ljq.entity.Person;
import com.ljq.utils.Consts;
import com.ljq.utils.DateUtils;
import com.ljq.utils.LuceneUtil;
import com.ljq.utils.XMLPropertyConfig; /**
* Lucene搜索方式大合集<br/><br/>
*
* Lucene搜索种类很多。这里就介绍几个最常用的。其中TermQuery\BooleanQuery\RegexQuery功能最强大,最为常用。
*
* @author 林计钦
* @version 1.0 2013-6-7 上午09:34:08
*/
public class IndexQueryTest { /**
* 词条搜索(单个关键字查找)<br/><br/>
*
* 主要对象是TermQuery,调用方式如下:<br/>
* Term term=new Term(字段名, 搜索关键字);<br/>
* Query query=new TermQuery(term);<br/>
* Hits hits=searcher.search(query);<br/>
* @throws Exception
*/
@Test
public void termQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); //Term term=new Term("ids", "1");
//Term term=new Term("ages", "20");
//Term term=new Term("birthdays", "2008-06-12");
//Term term=new Term("name", "张三");
Term term=new Term("city", "厦门"); Query query=new TermQuery(term);
TopDocs topDocs=searcher.search(query, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 组合搜索(允许多个关键字组合搜索)<br/><br/>
*
* 主要对象是BooleanQuery,调用方式如下:<br/>
* Term term1=new Term(字段名, 搜索关键字);<br/>
* TermQuery query1=new TermQuery(term1);<br/><br/>
*
* Term term2=new Term(字段名, 搜索关键字);<br/>
* TermQuery query2=new TermQuery(term2);<br/><br/>
*
* BooleanQuery booleanQuery=new BooleanQuery();<br/>
* booleanQuery.add(query1, 参数);<br/>
* booleanQuery.add(query2, 参数);<br/><br/>
*
* Hits hits=searcher.search(booleanquery);<br/>
* 此方法中的核心在BooleanQuery的add方法上,其第二个参数有三个可选值,对应着逻辑上的与或非关系。<br/><br/>
*
* 参数如下:<br/>
* BooleanClause.Occur.MUST:必须包含,类似于逻辑运算的与<br/>
* BooleanClause.Occur.MUST_NOT:必须不包含,类似于逻辑运算的非<br/>
* BooleanClause.Occur.SHOULD:可以包含,类似于逻辑运算的或<br/>
* 这三者组合,妙用无穷。<br/>
* @throws Exception
*/
@Test
public void booleanQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); //组合条件:
//年龄(或):10、20、30、40
//名字(与): 四
//城市(非): 莆田
TermQuery ageQuery10=new TermQuery(new Term("ages", "10"));
TermQuery ageQuery20=new TermQuery(new Term("ages", "20"));
TermQuery ageQuery30=new TermQuery(new Term("ages", "30"));
TermQuery ageQuery40=new TermQuery(new Term("ages", "40")); TermQuery nameQuery=new TermQuery(new Term("name", "四")); TermQuery cityQuery=new TermQuery(new Term("city", "莆田")); BooleanQuery booleanQuery=new BooleanQuery();
booleanQuery.add(ageQuery10, BooleanClause.Occur.SHOULD);
booleanQuery.add(ageQuery20, BooleanClause.Occur.SHOULD);
booleanQuery.add(ageQuery30, BooleanClause.Occur.SHOULD);
booleanQuery.add(ageQuery40, BooleanClause.Occur.SHOULD);
booleanQuery.add(nameQuery, BooleanClause.Occur.MUST);
booleanQuery.add(cityQuery, BooleanClause.Occur.MUST_NOT); TopDocs topDocs=searcher.search(booleanQuery, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 范围搜索(允许搜索指定范围内的关键字结果)<br/><br/>
*
* 主要对象是TermRangeQuery,调用方式如下:<br/>
* TermRangeQuery rangequery=new TermRangeQuery(字段名, 起始值, 终止值, 起始值是否包含边界, 终止值是否包含边界); <br/><br/>
*
* Hits hits=searcher.search(rangequery);<br/>
* 此方法中的参数是Boolean类型的,表示是否包含边界 。<br/>
* true 包含边界<br/>
* false不包含边界<br/>
* @throws Exception
*/
@Test
public void rangeQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); TermRangeQuery idQuery=new TermRangeQuery("ids", "1", "3", true, true);
TermRangeQuery ageQuery=new TermRangeQuery("ages", "10", "30", true, true);
TermRangeQuery timeQuery=new TermRangeQuery("birthdays", "2011-03-09", "2013-01-07", true, true); TopDocs topDocs=searcher.search(timeQuery, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 前缀搜索(搜索起始位置符合要求的结果)<br/><br/>
*
* 主要对象是PrefixQuery,调用方式如下:<br/>
* Term term=new Term(字段名, 搜索关键字);<br/>
* PrefixQuery prefixquery=new PrefixQuery(term);<br/>
* Hits hits=searcher.search(prefixquery);<br/>
*
* @throws Exception
*/
@Test
public void prefixQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); Term term=new Term("name", "王");
PrefixQuery prefixquery=new PrefixQuery(term); TopDocs topDocs=searcher.search(prefixquery, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 短语搜索(根据零碎的短语组合成新的词组进行搜索)<br/><br/>
*
* 主要对象是PhraseQuery,调用方式如下:<br/>
* Term term1=new Term(字段名, 搜索关键字);<br/>
* Term term2=new Term(字段名, 搜索关键字);<br/><br/>
*
* PhraseQuery phrasequery=new PhraseQuery();<br/>
* phrasequery.setSlop(参数);<br/>
* phrasequery.add(term1);<br/>
* phrasequery.add(term2);<br/>
* Hits hits=searcher.search(phrasequery);<br/>
* 其中setSlop的参数是设置两个关键字之间允许间隔的最大值。<br/>
* @throws Exception
*/
@Test
public void phraseQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); Term term1=new Term("name", "林");
Term term2=new Term("name", "钦"); PhraseQuery phrasequery=new PhraseQuery();
phrasequery.setSlop(100);
phrasequery.add(term1);
phrasequery.add(term2); TopDocs topDocs=searcher.search(phrasequery, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 多短语搜索(先指定一个前缀关键字,然后其他的关键字加在此关键字之后,组成词语进行搜索)<br/><br/>
*
* 主要对象是MultiPhraseQuery,调用方式如下:<br/>
*
* Term term=new Term(字段名,前置关键字);<br/>
* Term term1=new Term(字段名,搜索关键字);<br/>
* Term term2=new Term(字段名,搜索关键字);<br/><br/>
*
* MultiPhraseQuery multiPhraseQuery=new MultiPhraseQuery();<br/><br/>
*
* multiPhraseQuery.add(term);<br/>
* multiPhraseQuery.add(new Term[]{term1, term2});<br/><br/>
*
* Hits hits=searcher.search(multiPhraseQuery);<br/>
* @throws Exception
*/
@Test
public void multiPhraseQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); //查询“计张”、“计钦”组合的关键词,先指定一个前缀关键字,然后其他的关键字加在此关键字之后,组成词语进行搜索
Term term=new Term("name", "计"); //前置关键字
Term term1=new Term("name", "张"); //搜索关键字
Term term2=new Term("name", "钦"); //搜索关键字 MultiPhraseQuery multiPhraseQuery=new MultiPhraseQuery();
multiPhraseQuery.add(term);
multiPhraseQuery.add(new Term[]{term1, term2}); TopDocs topDocs=searcher.search(multiPhraseQuery, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 模糊搜索(顾名思义)<br/><br/>
*
* 主要对象是FuzzyQuery,调用方式如下:<br/><br/>
*
* Term term=new Term(字段名, 搜索关键字);<br/>
* FuzzyQuery fuzzyquery=new FuzzyQuery(term,参数);<br/>
* Hits hits=searcher.search(fuzzyquery);<br/>
* 此中的参数是表示模糊度,是小于1的浮点小数,比如0.5f
* @throws Exception
*/
@Test
public void fuzzyQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); Term term=new Term("name", "三张");
FuzzyQuery fuzzyquery=new FuzzyQuery(term, 0.5f); TopDocs topDocs=searcher.search(fuzzyquery, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 通配符搜索(顾名思义)<br/><br/>
*
* 主要对象是:WildcardQuery,调用方式如下:<br/><br/>
*
* Term term=new Term(字段名,搜索关键字+通配符);<br/>
* WildcardQuery wildcardquery=new WildcardQuery(term);<br/>
* Hits hits=searcher.search(wildcardquery);<br/><br/>
*
* 其中的通配符分两种,即*和?<br/>
* * 表示任意多的自负<br/>
* ?表示任意一个字符
* @throws Exception
*/
@Test
public void wildcardQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); Term term=new Term("name", "三?");
WildcardQuery wildcardQuery=new WildcardQuery(term); TopDocs topDocs=searcher.search(wildcardQuery, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 正则表达式搜索(顾名思义,这个类引入lucene-queries-3.5.0.jar包)<br/><br/>
*
* 主要对象是:RegexQuery,调用方式如下 <br/>
* String regex = ".*"; <br/>
* Term term = new Term (search_field_name, regex); <br/>
* RegexQuery query = new RegexQuery (term); <br/>
* TopDocs hits = searcher.search (query, 100); <br/>
* @throws Exception
*/
@Test
public void regexQuery() throws Exception {
IndexReader reader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
IndexSearcher searcher = new IndexSearcher(reader); String regex = "林*";
Term term=new Term("name", regex);
RegexQuery query = new RegexQuery(term); TopDocs topDocs=searcher.search(query, 1000);
System.out.println("共检索出 " + topDocs.totalHits + " 条记录");
System.out.println(); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scDoc : scoreDocs) {
Document document = searcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度 System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s, 相关度:%s.",
id, name, age, city, DateUtils.longToString(Long.parseLong(birthday), Consts.FORMAT_SHORT), score));
} searcher.close();
reader.close();
} /**
* 数值范围过滤器,如:int、long、float类型等
*
* @throws Exception
*/
@Test
public void numericFilter() throws Exception{ //CustomScoreQuery
//Filter filter = NumericRangeFilter.newLongRange("id", 1l, 3l, true, true);
Filter filter = NumericRangeFilter.newIntRange("age", 1, 39, true, true);
List<Person> persons=search(filter, new String[]{"name","city"}, "厦门");
for(Person person : persons){
System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s.",
person.getId(), person.getName(), person.getAge(), person.getCity(), DateUtils.dateToString(person.getBirthday(), Consts.FORMAT_SHORT)));
}
} /**
* 时间范围过滤器
* @throws Exception
*/
@Test
public void dateFilter() throws Exception{
//2008-06-12
long min=DateUtils.stringToDate("2008-06-12", Consts.FORMAT_SHORT).getTime();
//2013-01-07
long max=DateUtils.stringToDate("2013-01-07", Consts.FORMAT_SHORT).getTime();
Filter filter = NumericRangeFilter.newLongRange("birthday", min, max, true, true);
List<Person> persons=search(filter, new String[]{"name","city"}, "厦门");
for(Person person : persons){
System.out.println(String.format("id:%s, name:%s, age:%s, city:%s, birthday:%s.",
person.getId(), person.getName(), person.getAge(), person.getCity(), DateUtils.dateToString(person.getBirthday(), Consts.FORMAT_SHORT)));
}
} /**
* 创建索引
*
* @throws Exception
*/
@Test
public void createIndex() throws Exception {
List<Document> docs = new ArrayList<Document>();
for (Person person : getPersons()) {
Document doc = new Document();
//声明为NumericField的字段,只能用NumericRangeFilter对象范围查询,不能用作关键字查询。
//NumericField不推荐,统一用Field
doc.add(new NumericField("id", Field.Store.YES, true).setLongValue(person.getId()));
doc.add(new NumericField("age", Field.Store.YES, true).setIntValue(person.getAge()));
doc.add(new NumericField("birthday", Field.Store.YES, true).setLongValue(person.getBirthday().getTime())); doc.add(new Field("ids", person.getId()+"", Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field("ages", person.getAge()+"", Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field("birthdays", DateUtils.dateToString(person.getBirthday(), Consts.FORMAT_SHORT),
Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field("name", person.getName(), Field.Store.YES, Field.Index.ANALYZED));
doc.add(new Field("city", person.getCity(), Field.Store.YES, Field.Index.ANALYZED)); docs.add(doc);
}
LuceneUtil.createIndex(docs);
} private List<Person> search(Filter filter, String[] fields, String keyword) {
List<Person> result = new ArrayList<Person>(); IndexSearcher indexSearcher = null;
TopDocs topDocs = null;
try {
// 创建索引搜索器,且只读
IndexReader indexReader = IndexReader.open(FSDirectory.open(new File(XMLPropertyConfig.getConfigXML().getString("index_path"))), true);
indexSearcher = new IndexSearcher(indexReader); MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_35,
fields, new IKAnalyzer());
Query query = queryParser.parse(keyword); // 返回前number条记录
if(filter == null){
topDocs=indexSearcher.search(query, 100000);
}else {
topDocs=indexSearcher.search(query, filter, 100000);
} // 信息展示
int totalCount = topDocs.totalHits;
System.out.println("共检索出 " + totalCount + " 条记录"); //高亮显示
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
QueryScorer fragmentScorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter, fragmentScorer);
Fragmenter fragmenter = new SimpleFragmenter(100);
highlighter.setTextFragmenter(fragmenter); ScoreDoc[] scoreDocs = topDocs.scoreDocs; for (ScoreDoc scDoc : scoreDocs) {
Document document = indexSearcher.doc(scDoc.doc);
String id = document.get("id");
String name = document.get("name");
String age = document.get("age");
String city = document.get("city");
String birthday = document.get("birthday");
float score = scDoc.score; //相似度
System.out.println("相似度:"+score); String lighterName = highlighter.getBestFragment(new IKAnalyzer(), "name", name);
if (null == lighterName) {
lighterName = name;
} String lighterAge = highlighter.getBestFragment(new IKAnalyzer(), "age", age);
if (null == lighterAge) {
lighterAge = age;
} String lighterCity= highlighter.getBestFragment(new IKAnalyzer(), "city", city);
if (null == lighterCity) {
lighterCity = city;
} String lighterBirthday = highlighter.getBestFragment(new IKAnalyzer(), "birthday", birthday);
if (null == lighterBirthday) {
lighterBirthday = birthday;
} Person person = new Person();
person.setId(Long.parseLong(id));
person.setName(lighterName);
person.setAge(NumberUtils.toInt(age));
person.setCity(lighterCity);
person.setBirthday(DateUtils.longToDate(Long.parseLong(lighterBirthday)));
result.add(person);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
} return result;
} private List<Person> getPersons() {
try {
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(1l, "张三", 10, "福州", DateUtils.stringToDate("2013-01-07", Consts.FORMAT_SHORT)));
persons.add(new Person(2l, "张四", 20, "莆田", DateUtils.stringToDate("2012-01-08", Consts.FORMAT_SHORT)));
persons.add(new Person(3l, "王五", 30, "泉州", DateUtils.stringToDate("2011-03-09", Consts.FORMAT_SHORT)));
persons.add(new Person(4l, "李四", 40, "厦门", DateUtils.stringToDate("2010-04-10", Consts.FORMAT_SHORT)));
persons.add(new Person(5l, "李白", 50, "漳州", DateUtils.stringToDate("2009-05-11", Consts.FORMAT_SHORT)));
persons.add(new Person(6l, "林计张三张三张三张三张三张三张三张三张三张三张三张三张三计钦", 60, "龙岩", DateUtils.stringToDate("2008-06-12", Consts.FORMAT_SHORT)));
return persons;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
} 2、LuceneUtil类:Lucene增删改工具类
package com.ljq.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.List; import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
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.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer; /**
* lucene工具类,采用IKAnalyzer中文分词器
*
* @author 林计钦
* @version 1.0 2013-6-3 下午03:51:29
*/
public class LuceneUtil {
/** 索引库路径 */
private static final String indexPath = XMLPropertyConfig.getConfigXML()
.getString("index_path");
public static IndexWriter indexWriter = null;
private static final Logger log=Logger.getLogger(LuceneUtil.class); public static IndexWriter getIndexWriter(){
if(indexWriter == null){
try {
//索引库路径不存在则新建一个
File indexFile=new File(indexPath);
if(!indexFile.exists()) indexFile.mkdir(); Directory fsDirectory = FSDirectory.open(indexFile);
IndexWriterConfig confIndex = new IndexWriterConfig(Version.LUCENE_35, new IKAnalyzer());
confIndex.setOpenMode(OpenMode.CREATE_OR_APPEND);
if (IndexWriter.isLocked(fsDirectory)) {
IndexWriter.unlock(fsDirectory);
}
indexWriter =new IndexWriter(fsDirectory, confIndex);
} catch (Exception e) {
e.printStackTrace();
}
}
return indexWriter;
} /**
* 创建索引
*
* @param doc
* @throws Exception
*/
public static boolean createIndex(Document doc) {
List<Document> docs = new ArrayList<Document>();
docs.add(doc);
return createIndex(docs);
} /**
* 创建索引
*
* @param docs
* @throws Exception
*/
public static boolean createIndex(List<Document> docs) {
try {
for (Document doc : docs) {
getIndexWriter().addDocument(doc);
}
// 优化操作
getIndexWriter().commit();
getIndexWriter().forceMerge(1); // forceMerge代替optimize
log.info("lucene create success.");
return true;
} catch (Exception e) {
log.error("lucene create failure.", e);
return false;
} finally {
if (getIndexWriter() != null) {
try {
getIndexWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} /**
* 更新索引
*
* 例如:Term term = new Term("id","1234567");
* 先去索引文件里查找id为1234567的Document,如果有就更新它(如果有多条,最后更新后只有一条),如果没有就新增。
* 数据库更新的时候,我们可以只针对某个列来更新,而lucene只能针对一行数据更新。
*
* @param field Document的Field(类似数据库的字段)
* @param value Field中的一个关键词
* @param doc
* @return
*/
public static boolean updateIndex(String field, String value, Document doc) {
try {
getIndexWriter().updateDocument(new Term(field, value), doc); log.info("lucene update success.");
return true;
} catch (Exception e) {
log.error("lucene update failure.", e);
return false;
}finally{
if(getIndexWriter()!=null){
try {
getIndexWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} /**
* 删除索引
*
* @param field Document的Field(类似数据库的字段)
* @param value Field中的一个关键词
* @param doc
* @return
*/
public static boolean deleteIndex(String field, String value) {
try {
getIndexWriter().deleteDocuments(new Term(field, value)); log.info("lucene delete success.");
return true;
} catch (Exception e) {
log.error("lucene delete failure.", e);
return false;
}finally{
if(getIndexWriter()!=null){
try {
getIndexWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} /**
* 删除整个索引库
*
* @return
*/
public static boolean deleteAllIndex() {
try {
getIndexWriter().deleteAll();
log.info("lucene delete all success.");
return true;
} catch (Exception e) {
log.error("lucene delete all failure.", e);
return false;
}finally{
if(getIndexWriter()!=null){
try {
getIndexWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} /**
* 判断索引库是否已创建
*
* @return true:存在,false:不存在
* @throws Exception
*/
public static boolean existsIndex() throws Exception {
File file = new File(indexPath);
if (!file.exists()) {
file.mkdirs();
}
String indexSufix = "/segments.gen";
// 根据索引文件segments.gen是否存在判断是否是第一次创建索引
File indexFile = new File(indexPath + indexSufix);
return indexFile.exists();
} }
												

Lucene搜索方式大合集的更多相关文章

  1. Lucene 搜索方式

    Lucene 的搜索方式包括:词项查询(TermQuery) / 布尔查询(BooleanQuery) / 短语查询(PhraseQuery) / 范围查询(RangeQuery) / 百搭查询(Wi ...

  2. [题解+总结]NOIP动态规划大合集

    1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...

  3. python字符串操作实方法大合集

    python字符串操作实方法大合集,包括了几乎所有常用的python字符串操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下:   #1.去空格及特殊符号 s.st ...

  4. NOIP动态规划大合集

    1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...

  5. [题解+总结]动态规划大合集II

    1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2. ...

  6. 直接拿来用!Facebook移动开源项目大合集

    直接拿来用!Facebook移动开源项目大合集 时间:2014-04-22 15:37 作者:唐小引 随着iOS依赖管理工具CocoaPods和大量第三方开源库成熟起来,业界积累了大量的优秀开源项目. ...

  7. 【Oracle教程资源大合集】Oracle数据库免费学习资源汇总

    Oracle的产品非常丰富,各类学习资源也五花八门,本文将介绍Oracle官方的免费教程与风哥整理的Oracle视频教程: 1.Oracle帮助中心 Oracle帮助中心也称为Oracle文档中心,这 ...

  8. HCNP学习笔记之史上最全华为路由器交换机配置命令大合集

    先来一张思科和华为命令的对照表: 史上最全华为路由器交换机配置命令大合集,熟练掌握下面的华为路由器交换机配置知识点,你只需花几分钟的时间就能明白华为路由器交换机配置.交换机的配置命令等等. 华为路由器 ...

  9. 动态规划大合集II

    1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2. ...

随机推荐

  1. tn文本分析语言(二) 基本语法

    tn是desert和tan共同开发的一种用于匹配,转写和抽取文本的语言.解释器使用Python实现,代码不超过1000行. 本文主要介绍tn的基本语法.高级内容可以参考其他篇章.使用这样的语法,是为了 ...

  2. JS查看Object对象的内容

    以一个例子来说,下面是他的Object: JS: 如果想直接获取到total的值,那就先把获取到的Json先Eval(),然后json.total就能取到total的值了, 但是如果想取到rows里面 ...

  3. 玩转Jquery,告别前端知道思路忘记知识点的痛苦

    本节内容: 本章主要讲解一下jquery,主要是工作中用的前端框架是datetables框架,然后datetables框架又是基于jqeury研发的,所以要想学一个东西,就必须要了解其底层,不然走路都 ...

  4. spring boot 配置启动后执行sql, 中文乱码

    spring.datasource.schema指定启动后执行的sql文件位置. 我发现中文乱码,原因是没有指定执行sql script encoding: spring: datasource: u ...

  5. 关于jqGrig如何写自定义格式化函数将JSON数据的字符串转换为表格各个列的值

    首先介绍一下jqGrid是一个jQuery的一个表格框架,现在有一个需求就是将数据库表的数据拿出来显示出来,分别有id,name,details三个字段,其中难点就是details字段,它的数据是这样 ...

  6. 我的angularjs源码学习之旅1——初识angularjs

    angular诞生有好几年光景了,有Google公司的支持版本更新还是比较快,从一开始就是一个热门技术,但是本人近期才开始接触到.只能感慨自己学习起点有点晚了.只能是加倍努力赶上技术前线. 因为有分析 ...

  7. 让你的网站免费支持 HTTPS 及 Nginx 平滑升级

    为什么要使用 HTTPS ? 首先来说一下 HTTP 与 HTTPS 协议的区别吧,他们的根本区别就是 HTTPS 在 HTTP 协议的基础上加入了 SSL 层,在传输层对网络连接进行加密.简单点说在 ...

  8. IIS与ASP.NET管道

    IIS 5.x与ASP.NET 我们先来看看IIS 5.x是如何处理基于ASP.NET资源(比如.aspx,.asmx等)请求的,整个过程基本上可以通过图1体现. IIS 5.x运行在进程InetIn ...

  9. Unity打开摄像头占满全屏

    Unity打开摄像头占满全屏 AR项目需求,Unity打开摄像头作为背景渲染占满全屏~ Unity对设备硬件操作的API并不是太友好~打开一个摄像头,渲染到屏幕上也都得自己写,虽然步骤少,提取摄像头t ...

  10. JavaScript中的匿名函数及函数的闭包

    1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没有函数名的函数. 1.1 函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式 第一种: ...