LuceneIndexLocation idsLocation = LuceneIndexLocation.getIndexLocation(config);
// TODO: maybe we should make this configurable. Imho this should not be a problem if enabled by default as once a search
// has been executed the Factory is opened and we only need to make sure that on shutdown it is released.
boolean reopenIndexFactory = true;
IndexAccessor indexAccessor = idsLocation.getAccessor(reopenIndexFactory);
if (indexAccessor == null) {
log.error("IndexAccessor is null. Search will not work.");
}
// Resources needed for faceted search
TaxonomyAccessor taAccessor = null;
TaxonomyReader taReader = null;
IndexReader facetsIndexReader = null;
IndexReader uniqueMimeTypesIndexReader = null;
List<String> uniqueMimeTypes = null;
if (retrieveUniqueMimeTypes) {
// retrieve all possible file types
uniqueMimeTypesIndexReader = indexAccessor.getReader(false);
final TermEnum termEnum = uniqueMimeTypesIndexReader.terms(new Term(LUCENE_INDEX_MIMETYPE, ""));
uniqueMimeTypes = new ArrayList<String>();
while (termEnum.next() && termEnum.term().field().equals(LUCENE_INDEX_MIMETYPE)) {
uniqueMimeTypes.add(termEnum.term().text());
}
}
// get accessors and reader only if facets are activated
if (facetsSearch.useFacets()) {
facetsIndexReader = indexAccessor.getReader(false);
taAccessor = idsLocation.getTaxonomyAccessor();
taReader = taAccessor.getTaxonomyReader();
}
searcher = indexAccessor.getPrioritizedSearcher();
Object userPermissionsObject = request.get(CRRequest.PERMISSIONS_KEY);
String[] userPermissions = new String[0];
if (userPermissionsObject instanceof String[]) {
userPermissions = (String[]) userPermissionsObject;
}
TopDocsCollector<?> collector = createCollector(searcher, hits, sorting, computescores, userPermissions);
HashMap<String, Object> result = null;
try {
analyzer = LuceneAnalyzerFactory.createAnalyzer(config);
if (searchedAttributes != null && searchedAttributes.length > 0 && query != null && !query.equals("")) {
QueryParser parser = CRQueryParserFactory.getConfiguredParser(searchedAttributes, analyzer, request, config);
Query parsedQuery = parser.parse(query);
// GENERATE A NATIVE QUERY
parsedQuery = searcher.rewrite(parsedQuery);
result = new HashMap<String, Object>(3);
result.put(RESULT_QUERY_KEY, parsedQuery);
// when facets are active create a FacetsCollector
FacetsCollector facetsCollector = null;
if (facetsSearch.useFacets()) {
facetsCollector = facetsSearch.createFacetsCollector(facetsIndexReader, taAccessor, taReader);
}
Map<String, Object> ret = executeSearcher(collector, searcher, parsedQuery, explain, count, start, facetsCollector);
if (log.isDebugEnabled()) {
for (Object res : ret.values()) {
if (res instanceof LinkedHashMap) {
LinkedHashMap<Document, Float> documents = (LinkedHashMap<Document, Float>) res;
if (documents != null) {
for (Entry doc : documents.entrySet()) {
Document doCument = (Document) doc.getKey();
log.debug("CRSearcher.search: "
/* + doCument.toString() */
+ " Contentid: " + doCument.get("contentid"));
}
}
}
}
}
if (ret != null) {
LinkedHashMap<Document, Float> coll = (LinkedHashMap<Document, Float>) ret.get(RESULT_RESULT_KEY);
float maxScore = (Float) ret.get(RESULT_MAXSCORE_KEY);
result.put(RESULT_RESULT_KEY, coll);
int totalhits = collector.getTotalHits();
result.put(RESULT_HITS_KEY, totalhits);
result.put(RESULT_MAXSCORE_KEY, maxScore);
if (retrieveUniqueMimeTypes) {
// add unique extensions
result.put(RESULT_UNIQUE_MIMETYPES_KEY, uniqueMimeTypes);
}
if (retrieveCollector) {
result.put(RESULT_COLLECTOR_KEY, ret.get(RESULT_COLLECTOR_KEY));
}
// PLUG IN DIDYOUMEAN
boolean didyoumeanEnabledForRequest = StringUtils.getBoolean(request.get(DIDYOUMEAN_ENABLED_KEY), true);
if (start == 0 && didyoumeanenabled && didyoumeanEnabledForRequest
&& (totalhits <= didyoumeanactivatelimit || didyoumeanactivatelimit == -1 || maxScore < didyoumeanminscore)) {
HashMap<String, Object> didyoumeanResult = didyoumean(
query,
parsedQuery,
indexAccessor,
parser,
searcher,
sorting,
userPermissions);
result.putAll(didyoumeanResult);
}
// PLUG IN DIDYOUMEAN END
// if a facetsCollector was created, store the faceted search results in the meta resolveable
if (facetsCollector != null) {
result.put(FacetsSearchConfigKeys.RESULT_FACETS_LIST_KEY, facetsSearch.getFacetsResults(facetsCollector));
}
int size = 0;
if (coll != null) {
size = coll.size();
}
log.debug("Fetched " + size + " objects with query: " + query);
} else {
result = null;
}
}
} catch (Exception e) {
if (config.getBoolean("FAILONMAXCLAUSES")) {
log.debug("Error getting the results.", e);
throw new CRException(e);
} else {
log.error("Error getting the results.", e);
result = null;
}
} finally {
/*
* if facets are activated cleanup the resources
* needed for faceted search
*
* Always cleanup/release the taxonomy Reader/Writer
* before the Reader/Writers of the main index!
*/
if (taAccessor != null && taReader != null) {
taAccessor.release(taReader);
}
if (facetsIndexReader != null) {
indexAccessor.release(facetsIndexReader, false);
}
if (uniqueMimeTypesIndexReader != null) {
indexAccessor.release(uniqueMimeTypesIndexReader, false);
}
indexAccessor.release(searcher);
}
return result;
}