package com.jspxcms.common.fulltext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NRTManager;
import org.apache.lucene.search.NRTManager.TrackingIndexWriter;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import com.jspxcms.common.orm.Limitable;
import com.jspxcms.common.orm.QuerydslUtils;
import com.mysema.query.lucene.LuceneQuery;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Predicate;
/**
* 近实时索引模板实现
*
* @author liufang
*
*/
public class NRTLuceneIndexTemplate implements LuceneIndexTemplate,
InitializingBean {
private TrackingIndexWriter trackingIndexWriter;
private NRTManager nrtManager;
public NRTLuceneIndexTemplate() {
}
public NRTLuceneIndexTemplate(TrackingIndexWriter trackingIndexWriter,
NRTManager nrtManager) {
this.trackingIndexWriter = trackingIndexWriter;
this.nrtManager = nrtManager;
}
public List<String> list(Query query, String field, Limitable limitable) {
IndexSearcher searcher = nrtManager.acquire();
try {
try {
int n = limitable.getLastResult();
n = n <= 0 ? 2000 : n;
TopDocs results = searcher.search(query, n);
int length = results.scoreDocs.length;
List<String> list = new ArrayList<String>(length);
for (ScoreDoc hit : results.scoreDocs) {
list.add(searcher.doc(hit.doc).get(field));
}
return list;
} finally {
nrtManager.release(searcher);
}
} catch (Exception e) {
throw new LuceneException("Error during searching.", e);
}
}
public Page<String> page(Query query, String field, Pageable pageable) {
IndexSearcher searcher = nrtManager.acquire();
try {
try {
int n = pageable.getOffset() + pageable.getPageSize();
TopDocs results = searcher.search(query, n);
int length = results.scoreDocs.length;
int size = length - pageable.getOffset();
List<String> content;
if (size > 0) {
content = new ArrayList<String>(size);
ScoreDoc hit;
for (int i = pageable.getOffset(); i < length; i++) {
hit = results.scoreDocs[i];
content.add(searcher.doc(hit.doc).get(field));
}
} else {
content = Collections.emptyList();
}
int total = results.totalHits;
return new PageImpl<String>(content, pageable, total);
} finally {
nrtManager.release(searcher);
}
} catch (Exception e) {
throw new LuceneException("Error during searching.", e);
}
}
public List<Document> list(Predicate predicate,
EntityPath<Document> entityPath, Limitable limitable) {
IndexSearcher searcher = nrtManager.acquire();
try {
try {
LuceneQuery query = new LuceneQuery(searcher);
query.where(predicate);
QuerydslUtils.applySorting(query, entityPath,
limitable.getSort());
Integer firstResult = limitable.getFirstResult();
if (firstResult != null && firstResult > 0) {
query.offset(firstResult);
}
Integer maxResults = limitable.getMaxResults();
if (maxResults != null && maxResults > 0) {
query.limit(maxResults);
}
return query.list();
} finally {
if (searcher != null) {
nrtManager.release(searcher);
}
}
} catch (Exception e) {
throw new LuceneException("Error during searching.", e);
}
}
public Page<Document> page(Predicate predicate,
EntityPath<Document> entityPath, Pageable pageable) {
IndexSearcher searcher = nrtManager.acquire();
try {
try {
LuceneQuery query = new LuceneQuery(searcher);
long total = query.count();
List<Document> content;
if (total > pageable.getOffset()) {
query.offset(pageable.getOffset());
query.limit(pageable.getPageSize());
QuerydslUtils.applySorting(query, entityPath,
pageable.getSort());
content = query.list();
} else {
content = Collections.emptyList();
}
Page<Document> page = new PageImpl<Document>(content, pageable,
total);
return page;
} finally {
if (searcher != null) {
nrtManager.release(searcher);
}
}
} catch (Exception e) {
throw new LuceneException("Error during searching.", e);
}
}
public void addDocument(Document document) {
try {
trackingIndexWriter.addDocument(document);
} catch (Exception e) {
throw new LuceneException("Error during adding a document.", e);
}
}
public void addDocuments(Collection<Document> documents) {
try {
trackingIndexWriter.addDocuments(documents);
} catch (Exception e) {
throw new LuceneException("Error during adding a document.", e);
}
}
public void updateDocument(Term term, Document document) {
try {
trackingIndexWriter.updateDocument(term, document);
} catch (Exception e) {
throw new LuceneException("Error during updating a document.", e);
}
}
public void deleteDocuments(Term... terms) {
try {
trackingIndexWriter.deleteDocuments(terms);
} catch (Exception e) {
throw new LuceneException("Error during deleting a document.", e);
}
}
public void deleteDocuments(Term term) {
try {
trackingIndexWriter.deleteDocuments(term);
} catch (Exception e) {
throw new LuceneException("Error during deleting a document.", e);
}
}
public void deleteDocuments(Query... queries) {
try {
trackingIndexWriter.deleteDocuments(queries);
} catch (Exception e) {
throw new LuceneException("Error during deleting a document.", e);
}
}
public void deleteDocuments(Query query) {
try {
trackingIndexWriter.deleteDocuments(query);
} catch (Exception e) {
throw new LuceneException("Error during deleting a document.", e);
}
}
public void deleteAll() {
try {
trackingIndexWriter.deleteAll();
} catch (Exception e) {
throw new LuceneException("Error during deleting a document.", e);
}
}
public void afterPropertiesSet() throws Exception {
if (trackingIndexWriter == null) {
throw new IllegalArgumentException(
"trackingIndexWriter is required");
}
if (nrtManager == null) {
throw new IllegalArgumentException("nrtManager is required");
}
}
public void setTrackingIndexWriter(TrackingIndexWriter trackingIndexWriter) {
this.trackingIndexWriter = trackingIndexWriter;
}
public void setNrtManager(NRTManager nrtManager) {
this.nrtManager = nrtManager;
}
}