Lucene 入門和簡單封裝
阿新 • • 發佈:2019-01-03
package com.whf.demo;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.lucene.analysis.Analyzer;
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.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
/**
* document(包含多個Field) Field(一個屬性) Analyzer(分詞處理) IndexWriter(建立索引)
* Directory(索引的儲存的位置,FSDirectory和RAMDirectory) Term(String field->String
* 待檢索的關鍵詞)
*
* @author whf
*
*/
public class LuceneManager {
private volatile static LuceneManager singleton = null;
private volatile static IndexWriter writer = null;
private volatile static IndexReader reader = null;
private volatile static IndexSearcher searcher = null;
private final Lock writerLock = new ReentrantLock();
private final static Object obj = new Object();
private static Version version = Version.LUCENE_CURRENT;
/**
* 單例建構函式
*
* @return
*/
private LuceneManager() {
}
/**
* 獲取LuceneTools單例例項(obj同步)
*
* @return
*/
public static LuceneManager getInstance() {
if (null == singleton) {
synchronized (obj) {
if (null == singleton) {
singleton = new LuceneManager();
}
}
}
return singleton;
}
/**
* 獲取IndexWriter單例例項(writerLock同步) 寫單例
*
* @param dir
* @param config
* @return
*/
public IndexWriter getIndexWriter(Directory dir, IndexWriterConfig config) {
if (dir == null)
throw new IllegalArgumentException("Directory can not be null.");
if (config == null)
throw new IllegalArgumentException(
"IndexWriterConfig can not be null.");
try {
writerLock.lock();
if (writer == null) {
if (IndexWriter.isLocked(dir)) {
throw new LockObtainFailedException(
"Directory of index had been locked.");
}
writer = new IndexWriter(dir, config);
}
} catch (LockObtainFailedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
writerLock.unlock();
}
return writer;
}
/**
* 獲取IndexReader物件 寫多例
*
* @param dir
* @param enableNRTReader
* 是否開啟NRTReader
* @return
*/
public IndexReader getIndexReader(Directory dir, boolean enableNRTReader) {
if (dir == null)
throw new IllegalArgumentException("Directory can not be null.");
try {
if (reader == null) {
reader = DirectoryReader.open(dir);
} else {
if (enableNRTReader && reader instanceof DirectoryReader) {
// 開啟近實時Reader,能立即看到動態新增/刪除的索引變化
reader = DirectoryReader
.openIfChanged((DirectoryReader) reader);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return reader;
}
/**
* 獲取IndexReader物件(預設不啟用NETReader)
*
* @param dir
* @return
*/
public IndexReader getIndexReader(Directory dir) {
return getIndexReader(dir, false);
}
/**
* 獲取IndexSearcher物件
*
* @param reader
* IndexReader物件例項
* @param executor
* 如果你需要開啟多執行緒查詢,請提供ExecutorService物件引數
* @return
*/
public IndexSearcher getIndexSearcher(IndexReader reader,
ExecutorService executor) {
if (reader == null)
throw new IllegalArgumentException(
"The indexReader can not be null.");
if (searcher == null)
searcher = new IndexSearcher(reader);
return searcher;
}
/**
* 獲取IndexSearcher物件(不支援多執行緒查詢)
*
* @param reader
* IndexReader物件例項
* @return
*/
public IndexSearcher getIndexSearcher(IndexReader reader) {
return getIndexSearcher(reader, null);
}
/**
* 建立QueryParser物件 QueryParser parser=new QueryParser("欄位名稱","分析器例項"); Query
* q=parser.parse("關鍵詞");
* parser.setDefaultOperator(QueryParser.Opertator.AND);
* 同時含有多個關鍵字,如果是QueryParser.Opertator.OR表示或者 IndexSearcher searcher=new
* IndexSearcher(reader); Hits hit=searcher.search(q);
*
* @param field
* @param analyzer
* @return
*/
public static QueryParser createQueryParser(String field, Analyzer analyzer) {
return new QueryParser(field, analyzer);
}
/**
* 建立QueryParser物件 QueryParser parser=new QueryParser("欄位名稱","分析器例項"); Query
* q=parser.parse("關鍵詞");
* parser.setDefaultOperator(QueryParser.Opertator.AND);
* 同時含有多個關鍵字,如果是QueryParser.Opertator.OR表示或者 IndexSearcher searcher=new
* IndexSearcher(reader); Hits hit=searcher.search(q);
*
* @param field
* @param analyzer
* @return
*/
public static QueryParser createMultiFieldQueryParser(String[] fields,
Analyzer analyzer) {
return new MultiFieldQueryParser(fields, analyzer);
}
/**
* 關閉IndexWriter
*
* @param writer
*/
public static void closeIndexWriter(IndexWriter writer) {
if (writer != null) {
try {
writer.close();
writer = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 關閉IndexReader
*
* @param reader
*/
public static void closeIndexReader(IndexReader reader) {
if (reader != null) {
try {
reader.close();
reader = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 關閉IndexReader和IndexWriter
*
* @param reader
* @param writer
*/
public static void closeAll(IndexReader reader, IndexWriter writer) {
closeIndexReader(reader);
closeIndexWriter(writer);
}
}
package com.whf.demo;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
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.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
import com.whf.pojo.HighlighterParam;
import com.whf.pojo.Page;
public class LuceneUtil {
private static final LuceneManager manager = LuceneManager.getInstance();
private static Analyzer analyzer = new IKAnalyzer(true);
private static Version version = Version.LUCENE_CURRENT;
private static FSDirectory fsDirectory = null;
private static RAMDirectory ramDirectory = null;
/**
* 開啟索引目錄
*
* @param luceneDir
* @return
* @throws IOException
*/
public static FSDirectory openFSDirectory(String luceneDir) {
if (fsDirectory == null)
try {
File dir = new File(luceneDir);
if (!dir.exists())
dir.mkdirs();
fsDirectory = FSDirectory.open(Paths.get(luceneDir));
// 注意:isLocked方法內部會試圖去獲取Lock,
// 如果獲取到Lock,會關閉它,否則return false表示索引目錄沒有被鎖.
// 這也就是為什麼unlock方法被從IndexWriter類中移除的原因
IndexWriter.isLocked(fsDirectory);
} catch (IOException e) {
e.printStackTrace();
}
return fsDirectory;
}
/**
* 開啟記憶體目錄
*
* @param luceneDir
* @return
* @throws IOException
*/
public static RAMDirectory openRAMDirectory() {
if (ramDirectory == null)
return new RAMDirectory();
else
return ramDirectory;
}
/**
* 關閉索引目錄並銷燬
*
* @param directory
* @throws IOException
*/
public static void closeDirectory(Directory directory) {
if (directory != null) {
try {
directory.close();
} catch (IOException e) {
e.printStackTrace();
}
directory = null;
}
}
/**
* 關閉IndexReader
*
* @param reader
*/
public static void closeIndexReader(IndexReader reader) {
if (reader != null) {
try {
reader.close();
reader = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 關閉IndexWriter
*
* @param writer
*/
public static void closeIndexWriter(IndexWriter writer) {
if (writer != null) {
try {
writer.close();
writer = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 關閉IndexReader和IndexWriter
*
* @param reader
* @param writer
*/
public static void closeAll(IndexReader reader, IndexWriter writer) {
closeIndexReader(reader);
closeIndexWriter(writer);
}
/**
* 獲取IndexWriter
*
* @param dir
* @param config
* @return
*/
public static IndexWriter getIndexWrtier(Directory dir,
IndexWriterConfig config) {
return manager.getIndexWriter(dir, config);
}
/**
* 獲取IndexWriter
*
* @param dir
* @param config
* @return
*/
public static IndexWriter getIndexWrtier(String directoryPath,
IndexWriterConfig config) {
FSDirectory directory = openFSDirectory(directoryPath);
return manager.getIndexWriter(directory, config);
}
/**
* 獲取IndexReader
*
* @param dir
* @param enableNRTReader
* 是否開啟NRTReader
* @return
*/
public static IndexReader getIndexReader(Directory dir,
boolean enableNRTReader) {
return manager.getIndexReader(dir, enableNRTReader);
}
/**
* 獲取IndexReader(預設不啟用NRTReader)
*
* @param dir
* @return
*/
public static IndexReader getIndexReader(Directory dir) {
return manager.getIndexReader(dir);
}
/**
* 獲取IndexSearcher
*
* @param reader
* IndexReader物件
* @param executor
* 如果你需要開啟多執行緒查詢,請提供ExecutorService物件引數
* @return
*/
public static IndexSearcher getIndexSearcher(IndexReader reader,
ExecutorService executor) {
return manager.getIndexSearcher(reader, executor);
}
/**
* 獲取IndexSearcher(不支援多執行緒查詢)
*
* @param reader
* IndexReader物件
* @return
*/
public static IndexSearcher getIndexSearcher(IndexReader reader) {
return manager.getIndexSearcher(reader);
}
/**
* 刪除索引[注意:請自己關閉IndexWriter物件]
*
* @param writer
* @param field
* @param value
*/
public static void deleteIndex(IndexWriter writer, String field,
String keyword) {
try {
writer.deleteDocuments(new Term[] { new Term(field, keyword) });
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 刪除索引[注意:請自己關閉IndexWriter物件]
*
* @param writer
* @param term
*/
public static void deleteIndexs(IndexWriter writer, Term[] terms) {
try {
writer.deleteDocuments(terms);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 刪除索引[注意:請自己關閉IndexWriter物件]
*
* @param writer
* @param field
* @param value
*/
public static void deleteIndex(IndexWriter writer, Term term) {
try {
writer.deleteDocuments(new Term[] { term });
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 批量刪除索引[注意:請自己關閉IndexWriter物件]
*
* @param writer
* @param querys
*/
public static void deleteIndexs(IndexWriter writer, Query[] querys) {
try {
writer.deleteDocuments(querys);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 刪除索引[注意:請自己關閉IndexWriter物件]
*
* @param writer
* @param query
*/
public static void deleteIndex(IndexWriter writer, Query query) {
try {
writer.deleteDocuments(query);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 刪除所有索引文件
*
* @param writer
*/
public static void deleteAllIndex(IndexWriter writer) {
try {
writer.deleteAll();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Term term = new Term("id","1234567");
* 先去索引檔案裡查詢id為1234567的Doc,如果有就更新它(如果有多條,最後更新後只有一條)。如果沒有就新增.
* 資料庫更新的時候,我們可以只針對某個列來更新,而lucene只能針對一行資料更新。
*
* @param writer
* @param term
* @param document
*/
public static void updateIndex(IndexWriter writer, Term term,
Document document) {
try {
writer.updateDocument(term, document);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 新增索引文件
*
* @param writer
* @param doc
*/
public static void addIndex(IndexWriter writer, Document document) {
updateIndex(writer, null, document);
// writer.addDocument(document);
}
/**
* 批量新增索引文件
*
* @param writer
* @param doc
*/
public static void addIndex(IndexWriter writer, List<Document> documents) {
try {
writer.addDocuments(documents);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 將記憶體的資料寫至外存
*
* @param writer
* @param ramDirectory
* @param fsramDirectory
* @param analyzer
*/
public static void OptimizeRAMToFSDirectory(IndexWriter writer,
Directory fsDirectory, Analyzer analyzer) {
try {
writer.addIndexes(new Directory[] { fsDirectory });
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 索引文件查詢
*
* @param searcher
* @param query
* @param sort
* @return
*/
public static List<Document> query(IndexSearcher searcher, Query query,
Integer rows, Sort sort, Filter filter) {
TopDocs topDocs = null;
List<Document> docList = null;
try {
if (sort != null) {
if (filter != null) {
topDocs = searcher.search(query, filter,
(rows == null ? Integer.MAX_VALUE : rows), sort);
} else {
topDocs = searcher.search(query,
(rows == null ? Integer.MAX_VALUE : rows), sort);
}
} else {
if (filter != null) {
topDocs = searcher.search(query, filter,
(rows == null ? Integer.MAX_VALUE : rows));
} else {
topDocs = searcher.search(query,
(rows == null ? Integer.MAX_VALUE : rows));
}
}
ScoreDoc[] scores = topDocs.scoreDocs;
int length = scores.length;
if (length <= 0) {
return Collections.emptyList();
}
docList = new ArrayList<Document>();
for (int i = 0; i < length; i++) {
System.out.println(scores[i].score + " " + scores[i].doc);
Document doc = searcher.doc(scores[i].doc);
docList.add(doc);
}
} catch (IOException e) {
e.printStackTrace();
}
return docList;
}
/**
* 返回索引文件的總數[注意:請自己手動關閉IndexReader]
*
* @param reader
* @return
*/
public static int getIndexTotalCount(IndexReader reader) {
return reader.numDocs();
}
/**
* 返回索引文件中最大文件ID[注意:請自己手動關閉IndexReader]
*
* @param reader
* @return
*/
public static int getMaxDocId(IndexReader reader) {
return reader.maxDoc();
}
/**
* 返回已經刪除尚未提交的文件總數[注意:請自己手動關閉IndexReader]
*
* @param reader
* @return
*/
public static int getDeletedDocNum(IndexReader reader) {
return getMaxDocId(reader) - getIndexTotalCount(reader);
}
/**
* 根據docId查詢索引文件
*
* @param reader
* IndexReader物件
* @param docID
* documentId
* @param fieldsToLoad
* 需要返回的field
* @return
*/
public static Document findDocumentByDocId(IndexReader reader, int docID,
Set<String> fieldsToLoad) {
try {
return reader.document(docID, fieldsToLoad);
} catch (IOException e) {
return null;
}
}
/**
* 根據docId查詢索引文件
*
* @param reader
* IndexReader物件
* @param docID
* documentId
* @return
*/
public static Document findDocumentByDocId(IndexReader reader, int docID) {
return findDocumentByDocId(reader, docID, null);
}
/**
* @Title: createHighlighter
* @Description: 建立高亮器
* @param query
* 索引查詢物件
* @param prefix
* 高亮字首字串
* @param stuffix
* 高亮字尾字串
* @param fragmenterLength
* 摘要最大長度
* @return
*/
public static Highlighter createHighlighter(Query query, String prefix,
String stuffix, int fragmenterLength) {
Formatter formatter = new SimpleHTMLFormatter((prefix == null || prefix
.trim().length() == 0) ? "<font color=\"red\">" : prefix,
(stuffix == null || stuffix.trim().length() == 0) ? "</font>"
: stuffix);
Scorer fragmentScorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter, fragmentScorer);
Fragmenter fragmenter = new SimpleFragmenter(fragmenterLength <= 0 ? 50
: fragmenterLength);
highlighter.setTextFragmenter(fragmenter);
return highlighter;
}
/**
* @Title: highlight
* @Description: 生成高亮文字
* @param document
* 索引文件物件
* @param highlighter
* 高亮器
* @param analyzer
* 索引分詞器
* @param field
* 高亮欄位
* @return
* @throws IOException
* @throws InvalidTokenOffsetsException
*/
public static String highlight(Document document, Highlighter highlighter,
Analyzer analyzer, String field) throws IOException {
List<IndexableField> list = document.getFields();
for (IndexableField fieldable : list) {
String fieldValue = fieldable.stringValue();
if (fieldable.name().equals(field)) {
try {
fieldValue = highlighter.getBestFragment(analyzer, field,
fieldValue);
} catch (InvalidTokenOffsetsException e) {
fieldValue = fieldable.stringValue();
}
return (fieldValue == null || fieldValue.trim().length() == 0) ? fieldable
.stringValue() : fieldValue;
}
}
return null;
}
/**
* @Title: searchTotalRecord
* @Description: 獲取符合條件的總記錄數
* @param query
* @return
* @throws IOException
*/
public static int searchTotalRecord(IndexSearcher search, Query query) {
ScoreDoc[] docs = null;
try {
TopDocs topDocs = search.search(query, Integer.MAX_VALUE);
if (topDocs == null || topDocs.scoreDocs == null
|| topDocs.scoreDocs.length == 0) {
return 0;
}
docs = topDocs.scoreDocs;
} catch (IOException e) {
e.printStackTrace();
}
return docs.length;
}
/**
* @Title: pageQuery
* @Description: Lucene分頁查詢
* @param searcher
* @param query
* @param page
* @throws IOException
*/
public static void pageQuery(IndexSearcher searcher, Directory directory,
Query query, Page<Document> page) {
int totalRecord = searchTotalRecord(searcher, query);
// 設定總記錄數
page.setTotalRecord(totalRecord);
TopDocs topDocs = null;
try {
topDocs = searcher.searchAfter(page.getAfterDoc(), query,
page.getPageSize());
} catch (IOException e) {
e.printStackTrace();
}
List<Document> docList = new ArrayList<Document>();
ScoreDoc[] docs = topDocs.scoreDocs;
int index = 0;
for (ScoreDoc scoreDoc : docs) {
int docID = scoreDoc.doc;
Document document = null;
try {
document = searcher.doc(docID);
} catch (IOException e) {
e.printStackTrace();
}
if (index == docs.length - 1) {
page.setAfterDoc(scoreDoc);
page.setAfterDocId(docID);
}
docList.add(document);
index++;
}
page.setItems(docList);
closeIndexReader(searcher.getIndexReader());
}
/**
* @Title: pageQuery
* @Description: 分頁查詢[如果設定了高亮,則會更新索引文件]
* @param searcher
* @param directory
* @param query
* @param page
* @param highlighterParam
* @param writerConfig
* @throws IOException
*/
public static void pageQuery(IndexSearcher searcher, Directory directory,
Query query, Page<Document> page,
HighlighterParam highlighterParam, IndexWriterConfig writerConfig)
throws IOException {
IndexWriter writer = null;
// 若未設定高亮
if (null == highlighterParam || !highlighterParam.isHighlight()) {
pageQuery(searcher, directory, query, page);
} else {
int totalRecord = searchTotalRecord(searcher, query);
System.out.println("totalRecord:" + totalRecord);
// 設定總記錄數
page.setTotalRecord(totalRecord);
TopDocs topDocs = searcher.searchAfter(page.getAfterDoc(), query,
page.getPageSize());
List<Document> docList = new ArrayList<Document>();
ScoreDoc[] docs = topDocs.scoreDocs;
int index = 0;
writer = getIndexWrtier(directory, writerConfig);
for (ScoreDoc scoreDoc : docs) {
int docID = scoreDoc.doc;
Document document = searcher.doc(docID);
String content = document.get(highlighterParam.getFieldName());
if (null != content && content.trim().length() > 0) {
// 建立高亮器
Highlighter highlighter = LuceneUtil.createHighlighter(
query, highlighterParam.getPrefix(),
highlighterParam.getStuffix(),
highlighterParam.getFragmenterLength());
String text = highlight(document, highlighter, analyzer,
highlighterParam.getFieldName());
// 若高亮後跟原始文字不相同,表示高亮成功
if (!text.equals(content)) {
Document tempdocument = new Document();
List<IndexableField> indexableFieldList = document
.getFields();
if (null != indexableFieldList
&& indexableFieldList.size() > 0) {
for (IndexableField field : indexableFieldList) {
if (field.name().equals(
highlighterParam.getFieldName())) {
tempdocument.add(new TextField(
field.name(), text, Store.YES));
} else {
tempdocument.add(field);
}
}
}
updateIndex(writer,
new Term(highlighterParam.getFieldName(),
content), tempdocument);
document = tempdocument;
}
}
if (index == docs.length - 1) {
page.setAfterDoc(scoreDoc);
page.setAfterDocId(docID);
}
docList.add(document);
index++;
}
page.setItems(docList);
}
closeIndexReader(searcher.getIndexReader());
closeIndexWriter(writer);
}
/**
* 建立QueryParser
*
* @return
*/
public static QueryParser createCustomQueryParser(String field,
Analyzer analyzer) {
return manager.createQueryParser(field, analyzer);
}
/**
* 建立多field的QueryParser
*
* @param fields
* @param analyzer
* @return
*/
public static QueryParser createMultiFieldQueryParser(String[] fields,
Analyzer analyzer) {
return manager.createMultiFieldQueryParser(fields, analyzer);
}
/**
* 可以在查詢的時候獲取TermVector
*
* @return
*/
public static Field storeVectorTextField(String name, String value,
Store store) {
FieldType type = new FieldType();
type.setStored(true);
type.setStoreTermVectors(true);
type.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
return new Field(name, value, type);
}
}
package com.whf.pojo;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.queries.CustomScoreProvider;
import org.apache.lucene.queries.CustomScoreQuery;
import org.apache.lucene.search.Query;
public class MyCountQuery extends CustomScoreQuery{
private String field=null;
private class MyCountQueryScoreProvider extends CustomScoreProvider{
private String field=null;
public MyCountQueryScoreProvider(LeafReaderContext context) {
super(context);
}
public MyCountQueryScoreProvider(LeafReaderContext context, String field) {
super(context);
this.field = field;
}
@Override
public float customScore(int arg0, float arg1, float[] arg2)
throws IOException {
IndexReader reader = context.reader();
Terms tv = reader.getTermVector(arg0, field);
TermsEnum termsEnum = null;
int numTerms = 0;
if (tv != null) {
termsEnum = tv.iterator();
while ((termsEnum.next()) != null) {
numTerms++;
}
}
return (float) (numTerms);
}
}
public MyCountQuery(Query subQuery) {
super(subQuery);
}
public MyCountQuery(Query subQuery, String field) {
super(subQuery);
this.field = field;
}
@Override
protected CustomScoreProvider getCustomScoreProvider(
LeafReaderContext context) throws IOException {
return new MyCountQueryScoreProvider(context, this.field);
}
}
package com.whf.pojo;
/**
* @ClassName: HighlighterParam
* @Description: 高亮器引數物件
* @author Lanxiaowei
* @date 2014-3-30 下午12:22:08
*/
public class HighlighterParam {
/** 是否需要設定高亮 */
private boolean highlight;
/** 需要設定高亮的屬性名 */
private String fieldName;
/** 高亮字首 */
private String prefix;
/** 高亮字尾 */
private String stuffix;
/** 顯示摘要最大長度 */
private int fragmenterLength;
public boolean isHighlight() {
return highlight;
}
public void setHighlight(boolean highlight) {
this.highlight = highlight;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getStuffix() {
return stuffix;
}
public void setStuffix(String stuffix) {
this.stuffix = stuffix;
}
public int getFragmenterLength() {
return fragmenterLength;
}
public void setFragmenterLength(int fragmenterLength) {
this.fragmenterLength = fragmenterLength;
}
public HighlighterParam(boolean highlight, String fieldName, String prefix,
String stuffix, int fragmenterLength) {
this.highlight = highlight;
this.fieldName = fieldName;
this.prefix = prefix;
this.stuffix = stuffix;
this.fragmenterLength = fragmenterLength;
}
public HighlighterParam(boolean highlight, String fieldName,
int fragmenterLength) {
this.highlight = highlight;
this.fieldName = fieldName;
this.fragmenterLength = fragmenterLength;
}
public HighlighterParam(boolean highlight, String fieldName, String prefix,
String stuffix) {
this.highlight = highlight;
this.fieldName = fieldName;
this.prefix = prefix;
this.stuffix = stuffix;
}
public HighlighterParam() {
}
}
package com.whf.pojo;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.queries.CustomScoreProvider;
import org.apache.lucene.queries.CustomScoreQuery;
import org.apache.lucene.search.Query;
public class MyCountQuery extends CustomScoreQuery{
private String field=null;
private class MyCountQueryScoreProvider extends CustomScoreProvider{
private String field=null;
public MyCountQueryScoreProvider(LeafReaderContext context) {
super(context);
}
public MyCountQueryScoreProvider(LeafReaderContext context, String field) {
super(context);
this.field