package org.digdata.swustoj.sort;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
/**
* Created by wwhhff11 on 16-8-15.
*/
public class LuceneSortFactory {
/**
* 获取排序对象
* 按照某个字段进行排序
*
* @param field
* @return
*/
public static Sort
getSortByField(String field, Boolean desc) {
Sort sort =
new Sort();
sort.setSort(
new SortField(field, SortField.Type.DOC, desc));
return sort;
}
}
package org.digdata.swustoj.sort;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
/**
* Created by wwhhff11 on 16-8-15.
*/
public class LuceneSortFactory {
/**
* 获取排序对象
* 按照某个字段进行排序
*
* @param field
* @return
*/
public static Sort
getSortByField(String field, Boolean desc) {
Sort sort =
new Sort();
sort.setSort(
new SortField(field, SortField.Type.DOC, desc));
return sort;
}
}
package org.digdata.swustoj.lucene;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TrackingIndexWriter;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.digdata.swustoj.sort.LuceneSortFactory;
import org.digdata.swustoj.util.PropertiesUtil;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by hongfei.whf on 2016/8/15.
*/
public class LuceneTemplate {
public static final int DEFAULT_MAXX_ROWS =
2000;
public static final int DEFAULT_MAXX_PAGE =
20;
public static final int DEFAULT_MAXX_PER_PAGE =
20;
private final String fileName =
"lucene-config.properties";
private Directory directory =
null;
private IndexWriterConfig cfg =
null;
private Analyzer analyzer =
null;
private IndexWriter writer =
null;
private TrackingIndexWriter trackingIndexWriter =
null;
private ControlledRealTimeReopenThread controlledRealTimeReopenThread =
null;
private SearcherManager searcherManager =
null;
/**
* 构造函数
*/
public LuceneTemplate() {
try {
String indexPath = PropertiesUtil.getPropertyByName(fileName,
"index.path");
directory =
new SimpleFSDirectory(Paths.get(indexPath));
analyzer =
new SmartChineseAnalyzer();
cfg =
new IndexWriterConfig(analyzer);
init();
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Getter
*
* @return
*/
public IndexWriter
getWriter() {
return writer;
}
/**
* 初始化
*
* @return
*/
public void init()
throws IOException {
if (writer ==
null) {
writer = openIndexWriter();
}
searcherManager =
new SearcherManager(writer,
false,
new SearcherFactory());
trackingIndexWriter =
new TrackingIndexWriter(writer);
controlledRealTimeReopenThread =
new ControlledRealTimeReopenThread<IndexSearcher>(
trackingIndexWriter, searcherManager,
5.0,
0.025);
controlledRealTimeReopenThread.setDaemon(
true);
controlledRealTimeReopenThread.start();
}
/**
* 销毁
*/
public void destory() {
try {
writer.commit();
writer.close();
directory.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* 开启写索引
*
* @return
*/
private IndexWriter
openIndexWriter()
throws IOException {
if (writer !=
null) {
return writer;
}
return writer =
new IndexWriter(directory, cfg);
}
/**
* 获得Searcher
*
* @return
*/
public IndexSearcher
openIndexSearcher()
throws Exception {
searcherManager.maybeRefresh();
return searcherManager.acquire();
}
/**
* 释放Searcher
*
* @param searcher
* @return
*/
public Boolean
releaseIndexSearcher(IndexSearcher searcher)
throws Exception {
try {
searcherManager.release(searcher);
}
catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 向索引增加文档
*
* @param document
* @return
*/
public Boolean
addDocumentWithCommit(Document document) {
try {
writer.addDocument(document);
writer.commit();
}
catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 向索引增加文档
*
* @param document
* @return
*/
public Boolean
addDocumentNotCommit(Document document) {
try {
writer.addDocument(document);
}
catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 向索引增加文档
*
* @param documents
* @return
*/
public Boolean
addDocumentWithCommit(List<Document> documents) {
try {
writer.addDocuments(documents);
writer.commit();
}
catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 向索引增加文档
*
* @param documents
* @return
*/
public Boolean
addDocumentNotCommit(List<Document> documents) {
try {
writer.addDocuments(documents);
}
catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 提交变更
*
* @return
*/
public Boolean
commit() {
try {
writer.commit();
}
catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 清空
*
* @return
*/
public Boolean
deleteAll() {
try {
writer.deleteAll();
writer.commit();
}
catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 查询
*
* @param searcher
* @param params
* @param rows
* @return
* @throws IOException
*/
public List<Document>
query(IndexSearcher searcher,
Map<String, Object> params, Integer rows)
throws IOException {
if (rows ==
null) {
rows = DEFAULT_MAXX_ROWS;
}
Query query = getMulitConditionQuery(params);
TopDocs topDocs = searcher.search(query, rows);
ScoreDoc[] hits = topDocs.scoreDocs;
List<Document> list =
new ArrayList<>();
for (
int i =
0; i < hits.length; i++) {
ScoreDoc hit = hits[i];
Document hitDoc = searcher.doc(hit.doc);
list.add(hitDoc);
}
return list;
}
/**
* 分页查询
*
* @param searcher
* @param params
* @param sort
* @param page
* @param rows
* @return
* @throws Exception
*/
public List<Document>
queryByPage(IndexSearcher searcher, Map<String, Object> params,
Sort sort, @NotNull Integer page,
@NotNull Integer rows)
throws Exception {
if (page <=
0) {
page =
1;
}
if (page > DEFAULT_MAXX_PAGE) {
page = DEFAULT_MAXX_PAGE;
}
if (rows > DEFAULT_MAXX_PER_PAGE) {
rows = DEFAULT_MAXX_PER_PAGE;
}
Query query = getMulitConditionQuery(params);
TopDocs topDocs = searcher.search(query, DEFAULT_MAXX_ROWS, sort);
ScoreDoc[] hits = topDocs.scoreDocs;
Integer start = (page -
1) * rows;
if (start > topDocs.totalHits) {
throw new Exception(
"totalHits is less than start");
}
Integer end = Math.min(start + rows, topDocs.totalHits);
List<Document> list =
new ArrayList<>();
for (
int i = start; i < end; i++) {
ScoreDoc hit = hits[i];
Document hitDoc = searcher.doc(hit.doc);
list.add(hitDoc);
}
return list;
}
/**
* 获取多条件查询
*
* @param params
* @return
*/
private BooleanQuery
getMulitConditionQuery(Map<String, Object> params) {
BooleanQuery booleanQuery =
new BooleanQuery();
for (Map.Entry<String, Object> entry : params.entrySet()) {
Object value = entry.getValue();
Query query =
null;
if (value.getClass() == String.class) {
query =
new TermQuery(
new Term(entry.getKey(), value.toString()));
}
else if (value.getClass() == Integer.class) {
query = NumericRangeQuery.newIntRange(entry.getKey(), (Integer) value, (Integer) value,
true,
true);
}
booleanQuery.add(query, BooleanClause.Occur.MUST);
}
return booleanQuery;
}
/**
* 测试入口
*
* @param args
*/
public static void main(String[] args)
throws Exception {
LuceneTemplate template =
new LuceneTemplate();
IndexWriter writer = template.getWriter();
template.deleteAll();
for (
int i =
0; i <
10; i++) {
Document doc =
new Document();
doc.add(
new IntField(
"id", i, IntField.TYPE_STORED));
doc.add(
new IntField(
"user_id",
2, IntField.TYPE_NOT_STORED));
doc.add(
new IntField(
"compiler_id",
3, IntField.TYPE_NOT_STORED));
doc.add(
new IntField(
"problem_id",
4, IntField.TYPE_NOT_STORED));
doc.add(
new IntField(
"status", i, IntField.TYPE_NOT_STORED));
doc.add(
new IntField(
"contest_id",
6, IntField.TYPE_NOT_STORED));
doc.add(
new TextField(
"username",
"wwhhff11", Field.Store.NO));
template.addDocumentNotCommit(doc);
}
template.commit();
IndexSearcher searcher = template.openIndexSearcher();
Map<String, Object> params =
new HashMap<>();
params.put(
"problem_id",
4);
params.put(
"username",
"wwhhff");
Sort sort = LuceneSortFactory.getSortByField(
"id",
true);
List<Document> docs = template.queryByPage(searcher, params, sort,
1,
5);
for (Document document : docs) {
System.out.println(document.get(
"id"));
}
template.releaseIndexSearcher(searcher);
template.destory();
}
}