📄 searchserviceimpl.java
字号:
/*
* Copyright 2003-2004 Michael Franken, Zilverline.
*
* The contents of this file, or the files included with this file, are subject to
* the current version of ZILVERLINE Collaborative Source License for the
* Zilverline Search Engine (the "License"); You may not use this file except in
* compliance with the License.
*
* You may obtain a copy of the License at
*
* http://www.zilverline.org.
*
* See the License for the rights, obligations and
* limitations governing use of the contents of the file.
*
* The Original and Upgraded Code is the Zilverline Search Engine. The developer of
* the Original and Upgraded Code is Michael Franken. Michael Franken owns the
* copyrights in the portions it created. All Rights Reserved.
*
*/
package org.zilverline.service;
import java.io.IOException;
import java.io.StringReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.DateField;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.BooleanQuery.TooManyClauses;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.zilverline.core.DocumentCollection;
import org.zilverline.core.FileSystemCollection;
import org.zilverline.core.IndexException;
import org.zilverline.core.Result;
import org.zilverline.core.SearchException;
import org.zilverline.core.SearchResult;
import org.zilverline.dao.DAOException;
import org.zilverline.dao.SearchServiceDAO;
import org.zilverline.lucene.BoostFactor;
import org.zilverline.lucene.BoostingParser;
/**
* Service that searches collections.
*
* @author Michael Franken
* @version $Revision: 1.8 $
*/
public final class SearchServiceImpl implements SearchService {
/** Access to collections, Populated through configuration. */
private transient CollectionManager collectionManager;
/** DAO for persisting SearchService. */
private transient SearchServiceDAO dao;
/** Array containing all boostable Fields. */
private transient String[] allBoostableFields = new String[] { "contents", "name", "summary", "title" };
/** logger for Commons logging. */
private transient Log log = LogFactory.getLog(SearchServiceImpl.class);
/** The default value for the number of results returned by a query. */
private int maxResults = 20;
/** The default search query. */
private String query = "";
/** Factors by which fields are boosted. */
private BoostFactor factors = new BoostFactor();
/**
* @return Returns the factors.
*/
public BoostFactor getFactors() {
return factors;
}
/**
* @param thoseFactors The factors to set.
*/
public void setFactors(final BoostFactor thoseFactors) {
this.factors = thoseFactors;
}
/**
* Gets the CollectionManager, which holds all collections, and contains default values for Collection.
*
* @return CollectionManager
*
* @see CollectionManager
*/
public CollectionManager getCollectionManager() {
return collectionManager;
}
/**
* @return Returns the dao.
*/
public SearchServiceDAO getDao() {
return dao;
}
/**
* Get the maximum number of results returned by a query.
*
* @return the number of results
*/
public int getMaxResults() {
return maxResults;
}
/**
* Gets the default search query.
*
* @return the query
*/
public String getQuery() {
return query;
}
/**
* Initializes the SearchService by reading defaults from DAO.
*
*/
public void init() {
SearchServiceImpl tempService = dao.load();
if (tempService != null) {
maxResults = tempService.getMaxResults();
query = tempService.getQuery();
factors = tempService.getFactors();
} else {
if (factors == null) {
factors = new BoostFactor();
}
}
}
/**
* Sets the CollectionManager, which holds all collections, and contains default values for Collection.
*
* @param cm CollectionManager
*
* @see CollectionManager
*/
public void setCollectionManager(final CollectionManager cm) {
collectionManager = cm;
}
/**
* @param thisDao The dao to set.
*/
public void setDao(final SearchServiceDAO thisDao) {
this.dao = thisDao;
}
/**
* Set the maximum number of results returned by a query.
*
* @param max value for the number of results.
*/
public void setMaxResults(final int max) {
maxResults = max;
}
/**
* Set the default query.
*
* @param thisQuery the default search query.
*/
public void setQuery(final String thisQuery) {
query = thisQuery;
}
/**
* Store the SearchService to store.
*
* @throws SearchException on error
*/
public void store() throws SearchException {
if (dao != null) {
try {
dao.store(this);
}
catch (DAOException e) {
throw new SearchException("Can not save collections", e);
}
} else {
log.error("No DAO set for SearchService");
}
}
/**
* Searches the given Collections for the query. Sending an empty or null array of names will betreated as if all collections
* need to be searched, which is handy for external queries, that can't know the names of collections.
*
* @param names array of collection names
* @param queryString the query
* @param startAt the first result to return (start counting from 0)
* @param numberOfResults the (maximum) number of results to return
* @return Object containing the results, and number of hits and the possibly changed startAt and endAt
*
* @throws SearchException if query can't be executed
*/
public SearchResult doSearch(final String[] names, final String queryString, int startAt, final int numberOfResults)
throws SearchException {
try {
MultiSearcher ms = null;
try {
// for given collections create a List of IndexSearchers
IndexSearcher[] allSearchers = createSearchersForCollectionsByName(names);
// prepare the query
// TODO: which analyzer to use? Different collections may have different Analyers
Analyzer analyzer = getCollectionManager().createAnalyzer();
log.debug("Using Analyzer " + analyzer.getClass());
// for each occurence of contents, add a boost for fields specified in BoostFactor
BoostingParser zp = new BoostingParser("contents", analyzer);
zp.setFactors(factors);
Query localquery = zp.parse(queryString);
log.debug("the Query: " + query);
// and search in all collections
ms = new MultiSearcher(allSearchers);
Hits hits = ms.search(localquery);
log.debug("Query " + queryString + ", with " + hits.length() + " hits");
// if we're changing the query, and we've paged too far
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -