com.jaeksoft.searchlib.result.ResultDocuments Maven / Gradle / Ivy
Show all versions of opensearchserver Show documentation
/**
* License Agreement for OpenSearchServer
*
* Copyright (C) 2012-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 .
**/
package com.jaeksoft.searchlib.result;
import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.function.expression.SyntaxError;
import com.jaeksoft.searchlib.index.ReaderInterface;
import com.jaeksoft.searchlib.index.ReaderLocal;
import com.jaeksoft.searchlib.query.ParseException;
import com.jaeksoft.searchlib.render.Render;
import com.jaeksoft.searchlib.render.RenderDocumentsJson;
import com.jaeksoft.searchlib.render.RenderDocumentsXml;
import com.jaeksoft.searchlib.request.AbstractRequest;
import com.jaeksoft.searchlib.request.DocumentsRequest;
import com.jaeksoft.searchlib.request.RequestInterfaces;
import com.jaeksoft.searchlib.result.collector.DocIdInterface;
import com.jaeksoft.searchlib.schema.*;
import com.jaeksoft.searchlib.util.IOUtils;
import com.jaeksoft.searchlib.util.Timer;
import com.jaeksoft.searchlib.util.array.IntBufferedArrayFactory;
import com.jaeksoft.searchlib.util.array.IntBufferedArrayInterface;
import com.jaeksoft.searchlib.webservice.query.document.IndexDocumentResult;
import com.jaeksoft.searchlib.webservice.query.document.IndexDocumentResult.IndexField;
import com.jaeksoft.searchlib.webservice.query.document.IndexDocumentResult.IndexTerm;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermFreqVector;
import org.roaringbitmap.IntIterator;
import org.roaringbitmap.RoaringBitmap;
import java.io.IOException;
import java.util.*;
public class ResultDocuments extends AbstractResult
implements ResultDocumentsInterface {
transient private ReaderInterface reader = null;
final private LinkedHashSet fieldNameSet;
final private int[] docArray;
private ResultDocuments(ReaderInterface reader, AbstractRequest request, LinkedHashSet fieldNameSet,
int[] docArray) {
super(request);
this.reader = reader;
this.fieldNameSet = fieldNameSet == null ? new LinkedHashSet() : fieldNameSet;
if (this.fieldNameSet.size() == 0 && request instanceof RequestInterfaces.ReturnedFieldInterface)
((RequestInterfaces.ReturnedFieldInterface) request).getReturnFieldList().populate(this.fieldNameSet);
this.docArray = docArray;
}
public ResultDocuments(ReaderInterface reader, AbstractRequest request, LinkedHashSet fieldNameSet,
List docList) {
this(reader, request, fieldNameSet, toDocArray(docList));
}
private final static int[] toDocArray(List docList) {
if (CollectionUtils.isEmpty(docList))
return null;
int[] docArray = new int[docList.size()];
int i = 0;
for (Integer docId : docList)
docArray[i++] = docId;
return docArray;
}
public ResultDocuments(ReaderLocal reader, DocumentsRequest request) throws IOException, SearchLibException {
this(reader, request, null, toDocArray(reader, request));
}
private final static int[] toDocArray(ReaderLocal reader, DocumentsRequest request) throws IOException {
SchemaField schemaField = null;
Schema schema = request.getConfig().getSchema();
String field = request.getField();
if (!StringUtils.isEmpty(field)) {
schemaField = schema.getField(field);
if (schemaField == null)
throw new IOException("Field not found: " + field);
} else {
schemaField = schema.getFieldList().getUniqueField();
if (schemaField == null)
throw new IOException("No unique field");
}
Collection uniqueKeys = request.getUniqueKeyList();
String fieldName = schemaField.getName();
return request.isReverse() ?
reverseDoc(reader, fieldName, uniqueKeys) :
sortedDoc(reader, fieldName, uniqueKeys);
}
private final static int[] sortedDoc(ReaderLocal reader, String fieldName, Collection uniqueKeys)
throws IOException {
int[] docIDs = new int[uniqueKeys.size()];
int i = 0;
for (String uniqueKey : uniqueKeys) {
TermDocs termDocs = reader.getTermDocs(new Term(fieldName, uniqueKey));
if (termDocs != null) {
try {
while (termDocs.next()) {
int doc = termDocs.doc();
if (!reader.isDeletedNoLock(doc))
docIDs[i++] = doc;
}
} finally {
IOUtils.close(termDocs);
}
}
}
if (i == docIDs.length)
return docIDs;
return Arrays.copyOf(docIDs, i);
}
private final static int[] reverseDoc(ReaderLocal reader, String fieldName, Collection uniqueKeys)
throws IOException {
int higher = -1;
RoaringBitmap bitSet = new RoaringBitmap();
for (String uniqueKey : uniqueKeys) {
TermDocs termDocs = reader.getTermDocs(new Term(fieldName, uniqueKey));
if (termDocs != null) {
try {
while (termDocs.next()) {
int doc = termDocs.doc();
if (doc > higher)
higher = doc;
bitSet.add(doc);
}
} finally {
IOUtils.close(termDocs);
}
}
}
bitSet.flip(0L, higher + 1);
IntBufferedArrayInterface intBufferArray =
IntBufferedArrayFactory.INSTANCE.newInstance(bitSet.getCardinality());
IntIterator iterator = bitSet.getIntIterator();
while (iterator.hasNext()) {
int docId = iterator.next();
if (!reader.isDeletedNoLock(docId))
intBufferArray.add(docId);
}
return intBufferArray.getFinalArray();
}
@Override
public ResultDocument getDocument(int pos, Timer timer) throws SearchLibException {
if (docArray == null || pos < 0 || pos > docArray.length)
return null;
try {
return new ResultDocument(fieldNameSet, docArray[pos], reader, getScore(pos), null, timer);
} catch (IOException e) {
throw new SearchLibException(e);
} catch (ParseException e) {
throw new SearchLibException(e);
} catch (SyntaxError e) {
throw new SearchLibException(e);
}
}
@Override
public void populate(List indexDocuments) throws IOException, SearchLibException {
SchemaFieldList schemaFieldList = request.getConfig().getSchema().getFieldList();
for (int docId : docArray) {
IndexDocumentResult indexDocument = new IndexDocumentResult(schemaFieldList.size());
Map storedFieldMap = reader.getDocumentStoredField(docId);
for (SchemaField schemaField : schemaFieldList) {
String fieldName = schemaField.getName();
List indexTermList = null;
if (schemaField.checkIndexed(Indexed.YES)) {
if (schemaField.getTermVector() == TermVector.NO) {
indexTermList = IndexTerm.toList(reader, fieldName, docId);
} else {
TermFreqVector termFreqVector = reader.getTermFreqVector(docId, fieldName);
indexTermList = IndexTerm.toList(termFreqVector);
}
}
IndexField indexField = new IndexField(fieldName, storedFieldMap.get(fieldName), indexTermList);
indexDocument.add(indexField);
}
indexDocuments.add(indexDocument);
}
}
@Override
public float getScore(int pos) {
return 0;
}
@Override
public Float getDistance(int pos) {
return null;
}
@Override
public int getCollapseCount(int pos) {
return 0;
}
@Override
public int getNumFound() {
if (docArray == null)
return 0;
return docArray.length;
}
@Override
protected Render getRenderXml() {
return new RenderDocumentsXml(this);
}
@Override
protected Render getRenderCsv() {
// TODO Auto-generated method stub
return null;
}
@Override
protected Render getRenderJson(boolean indent) {
return new RenderDocumentsJson(this, indent);
}
@Override
public Iterator iterator() {
return new ResultDocumentIterator(this, null);
}
@Override
public int getDocumentCount() {
return docArray == null ? 0 : docArray.length;
}
@Override
public int getRequestStart() {
return 0;
}
@Override
public int getRequestRows() {
return docArray == null ? 0 : docArray.length;
}
@Override
public DocIdInterface getDocs() {
return null;
}
public int[] getDocIdArray() {
return docArray;
}
@Override
public float getMaxScore() {
return 0;
}
@Override
public int getCollapsedDocCount() {
return 0;
}
}