/**
* License Agreement for OpenSearchServer
*
* Copyright (C) 2008-2015 Emmanuel Keller / Jaeksoft
*
* http://www.open-search-server.com
*
* This file is part of OpenSearchServer.
*
* OpenSearchServer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenSearchServer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenSearchServer.
* If not, see <http://www.gnu.org/licenses/>.
**/
package com.jaeksoft.searchlib.result;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.collapse.CollapseFunctionField;
import com.jaeksoft.searchlib.facet.FacetList;
import com.jaeksoft.searchlib.facet.FacetListExecutor;
import com.jaeksoft.searchlib.function.expression.SyntaxError;
import com.jaeksoft.searchlib.index.DocSetHits;
import com.jaeksoft.searchlib.index.ReaderAbstract;
import com.jaeksoft.searchlib.join.JoinList;
import com.jaeksoft.searchlib.join.JoinResult;
import com.jaeksoft.searchlib.query.ParseException;
import com.jaeksoft.searchlib.request.AbstractLocalSearchRequest;
import com.jaeksoft.searchlib.request.SearchFilterRequest;
import com.jaeksoft.searchlib.result.collector.CollapseDocInterface;
import com.jaeksoft.searchlib.result.collector.DocIdInterface;
import com.jaeksoft.searchlib.result.collector.JoinDocInterface;
import com.jaeksoft.searchlib.schema.FieldValue;
import com.jaeksoft.searchlib.sort.SortFieldList;
import com.jaeksoft.searchlib.sort.SorterAbstract;
import com.jaeksoft.searchlib.util.Timer;
import com.jaeksoft.searchlib.webservice.query.document.IndexDocumentResult;
public class ResultSearchSingle extends AbstractResultSearch<AbstractLocalSearchRequest> {
transient private DocSetHits docSetHits;
transient private final LinkedHashSet<String> fieldNameSet;
private final ResultDocument[] resultDocuments;
/**
* The constructor executes the request using the searcher provided and
* computes the facets.
*
* @param searcher
* @param request
* @throws IOException
* @throws ParseException
* @throws SyntaxError
* @throws SearchLibException
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public ResultSearchSingle(ReaderAbstract reader, AbstractLocalSearchRequest searchRequest)
throws IOException, ParseException, SyntaxError, SearchLibException, InstantiationException,
IllegalAccessException, ClassNotFoundException {
super(reader, searchRequest);
docSetHits = reader.searchDocSet(searchRequest, timer);
numFound = docSetHits.getNumFound();
DocIdInterface notCollapsedDocs = docSetHits.getCollector(DocIdInterface.class);
CollapseDocInterface collapsedDocs = null;
JoinResult[] joinResults = null;
SortFieldList sortFieldList = searchRequest.getSortFieldList();
// Are we doing join
if (searchRequest.isJoin()) {
Timer joinTimer = new Timer(timer, "join");
JoinList joinList = searchRequest.getJoinList();
joinResults = new JoinResult[joinList.size()];
Timer t = new Timer(joinTimer, "join - apply");
notCollapsedDocs = joinList.apply(searchRequest, reader, notCollapsedDocs, joinResults, t);
t.getDuration();
t = new Timer(joinTimer, "join - sort");
if (sortFieldList != null) {
SorterAbstract sorter = sortFieldList.getSorter(notCollapsedDocs, reader);
if (sorter != null)
sorter.quickSort(t);
sortFieldList = null;
}
t.getDuration();
numFound = notCollapsedDocs.getSize();
if (this.facetList == null)
this.facetList = new FacetList();
for (JoinResult joinResult : joinResults)
joinResult.populate(this.facetList);
joinTimer.getDuration();
}
// Handling sorting
if (sortFieldList != null && !(request instanceof SearchFilterRequest)) {
SorterAbstract sorter = sortFieldList.getSorter(notCollapsedDocs, reader);
if (sorter != null)
sorter.quickSort(timer);
}
// Are we doing collapsing ?
if (collapse != null) {
collapsedDocs = collapse.collapse(reader, notCollapsedDocs, timer);
collapsedDocCount = collapsedDocs == null ? 0 : collapsedDocs.getCollapsedCount();
Collection<CollapseFunctionField> functionFields = request.getCollapseFunctionFields();
if (functionFields != null)
for (CollapseFunctionField functionField : functionFields)
functionField.prepareExecute(request, reader, collapsedDocs);
}
// We compute facet
if (searchRequest.isFacet())
new FacetListExecutor(searchRequest.getConfig(), reader, notCollapsedDocs, collapsedDocs,
searchRequest.getFacetFieldList(), facetList, timer);
// No collapsing
if (collapsedDocs == null) {
if (notCollapsedDocs != null)
setDocs(notCollapsedDocs);
else
setDocs(docSetHits.getCollector(DocIdInterface.class));
} else {
// With collapsing
setDocs(collapsedDocs);
// Update joinResults
if (joinResults != null)
for (JoinResult joinResult : joinResults)
joinResult.setJoinDocInterface(collapsedDocs.getCollector(JoinDocInterface.class));
}
if (joinResults != null)
setJoinResults(joinResults);
maxScore = request.isScoreRequired() ? docSetHits.getMaxScore() : 0;
fieldNameSet = new LinkedHashSet<String>();
searchRequest.getReturnFieldList().populate(fieldNameSet);
searchRequest.getSnippetFieldList().populate(fieldNameSet);
int rows = docs.getSize() - request.getStart();
rows = Math.min(rows, request.getRows());
if (rows <= 0) {
resultDocuments = null;
return;
}
resultDocuments = new ResultDocument[rows];
int pos = request.getStart();
for (int i = 0; i < rows; i++)
resultDocuments[i] = getLazyDocument(pos++, timer);
}
/**
* Returns the searcher used to build the result.
*
* @return Searcher
*/
@Override
public ReaderAbstract getReader() {
return reader;
}
/**
*
* @return DocSetHits.
*/
public DocSetHits getDocSetHits() {
return this.docSetHits;
}
@Override
public ResultDocument getDocument(int pos, final Timer timer) throws SearchLibException {
pos = pos - request.getStart();
if (resultDocuments == null || pos < 0 || pos >= resultDocuments.length)
return null;
return resultDocuments[pos];
}
public ResultDocument getLazyDocument(final int pos, final Timer timer) throws SearchLibException {
if (docs == null || pos < 0 || pos >= docs.getSize())
return null;
try {
int docId = docs.getIds()[pos];
float score = scores != null ? scores.getScores()[pos] : 0;
if (!(docs instanceof CollapseDocInterface)) {
return new ResultDocument(request, fieldNameSet, docId, reader, score, null, 0, timer);
}
int[] collapsedDocs = ((CollapseDocInterface) docs).getCollapsedDocs(pos);
ResultDocument resultDocument = new ResultDocument(request, fieldNameSet, docId, reader, score, null,
collapsedDocs == null ? 0 : collapsedDocs.length, timer);
Collection<CollapseFunctionField> functionFields = request.getCollapseFunctionFields();
if (functionFields != null && collapsedDocs != null)
for (CollapseFunctionField functionField : functionFields)
resultDocument.addFunctionField(functionField, reader, pos, timer);
if (request.getCollapseMax() > 0)
return resultDocument;
if (collapsedDocs != null) {
for (int doc : collapsedDocs) {
ResultDocument rd = new ResultDocument(request, fieldNameSet, doc, reader, 0, null, 0, timer);
resultDocument.addCollapsedDocument(rd);
for (String field : fieldNameSet) {
FieldValue fieldValue = resultDocument.getReturnFields().get(field);
if (fieldValue != null && fieldValue.getValuesCount() > 0)
continue;
resultDocument.addReturnedFields(rd.getReturnFields().get(field));
}
}
}
return resultDocument;
} catch (IOException e) {
throw new SearchLibException(e);
} catch (ParseException e) {
throw new SearchLibException(e);
} catch (SyntaxError e) {
throw new SearchLibException(e);
} catch (java.text.ParseException e) {
throw new SearchLibException(e);
} catch (InstantiationException e) {
throw new SearchLibException(e);
} catch (IllegalAccessException e) {
throw new SearchLibException(e);
}
}
@Override
public void populate(List<IndexDocumentResult> indexDocuments) throws IOException, SearchLibException {
throw new SearchLibException("Method not available");
}
}