if (attr instanceof EmptySearchAttribute) {
hasEmptySearchFields = true;
}
}
Result intermediateResult;
// only do "normal" query if no other sources are present
// use filters to filter sources otherwise
if (distanceSearch == null && !sources.isEmpty()) {
intermediateResult = new Result(new ArrayList<AbstractNode>(), null, false, false);
} else {
BooleanQuery query = new BooleanQuery();
boolean allExactMatch = true;
// build query
for (SearchAttribute attr : rootGroup.getSearchAttributes()) {
Query queryElement = attr.getQuery();
if (queryElement != null) {
query.add(queryElement, attr.getOccur());
}
allExactMatch &= attr.isExactMatch();
}
QueryContext queryContext = new QueryContext(query);
IndexHits hits = null;
if (sortKey != null) {
Integer sortType = sortKey.getSortType();
if (sortType != null) {
queryContext.sort(new Sort(new SortField(sortKey.dbName(), sortType, sortDescending)));
} else {
queryContext.sort(new Sort(new SortField(sortKey.dbName(), Locale.getDefault(), sortDescending)));
}
}
if (distanceSearch != null) {
if (coords != null) {
Map<String, Object> params = new HashMap<>();
params.put(LayerNodeIndex.POINT_PARAMETER, coords.toArray());
params.put(LayerNodeIndex.DISTANCE_IN_KM_PARAMETER, dist);
LayerNodeIndex spatialIndex = this.getSpatialIndex();
if (spatialIndex != null) {
synchronized (spatialIndex) {
hits = spatialIndex.query(LayerNodeIndex.WITHIN_DISTANCE_QUERY, params);
}
}
}
// instantiate spatial search results without paging,
// as the results must be filtered by type anyway
intermediateResult = new NodeFactory(securityContext).instantiate(hits);
} else if (allExactMatch) {
index = getKeywordIndex();
synchronized (index) {
try {
hits = index.query(queryContext);
} catch (NumberFormatException nfe) {
logger.log(Level.SEVERE, "Could not sort results", nfe);
// retry without sorting
queryContext.sort(null);
hits = index.query(queryContext);
}
}
// all luecene query, do not filter results
filterResults = hasEmptySearchFields;
intermediateResult = factory.instantiate(hits);
} else {
// Default: Mixed or fulltext-only search: Use fulltext index
index = getFulltextIndex();
synchronized (index) {
try {
hits = index.query(queryContext);
} catch (NumberFormatException nfe) {
logger.log(Level.SEVERE, "Could not sort results", nfe);
// retry without sorting
queryContext.sort(null);
hits = index.query(queryContext);
}
}
// all luecene query, do not filter results
filterResults = hasEmptySearchFields;
intermediateResult = factory.instantiate(hits);
}
if (hits != null) {
hits.close();
}
}
if (filterResults) {
// sorted result set
Set<GraphObject> intermediateResultSet = new LinkedHashSet<>(intermediateResult.getResults());
List<GraphObject> finalResult = new LinkedList<>();
int resultCount = 0;
// We need to find out whether there was a source for any of the possible sets that we want to merge.
// If there was only a single source, the final result is the result of that source. If there are
// multiple sources, the result is the intersection of all the sources, depending on the occur flag.
if (hasGraphSources) {
// merge sources according to their occur flag
final Set<GraphObject> mergedSources = mergeSources(sources);
if (hasSpatialSource) {
// CHM 2014-02-24: preserve sorting of intermediate result, might be sorted by distance which we cannot reproduce easily
intermediateResultSet.retainAll(mergedSources);
} else {
intermediateResultSet.addAll(mergedSources);
}
}
// CHM 2014-02-10: this is probably wrong but left here
// because I'm not sure, replaced by the code above
// if (intermediateResultSet.isEmpty()) {
//
// // merge sources according to their occur flag
// intermediateResultSet.addAll(mergeSources(sources));
//
// } else if (!sources.isEmpty()) {
//
// // merge sources according to their occur flag
// intermediateResultSet.retainAll(mergeSources(sources));
// }
// Filter intermediate result
for (GraphObject obj : intermediateResultSet) {
boolean addToResult = true;
// check all attributes before adding a node
for (SearchAttribute attr : rootGroup.getSearchAttributes()) {
// check all search attributes
addToResult &= attr.includeInResult(obj);
}
if (addToResult) {
finalResult.add(obj);
resultCount++;
}
}
// sort list
Collections.sort(finalResult, new GraphObjectComparator(sortKey, sortDescending));
// return paged final result
return new Result(PagingHelper.subList(finalResult, pageSize, page, offsetId), resultCount, true, false);
} else {
// no filtering
return intermediateResult;