if (!preparedIndices.contains(query.getSite().getIdentifier())) {
try {
createIndex(query.getSite());
} catch (IOException e) {
throw new ContentRepositoryException(e);
}
}
logger.debug("Searching index using query '{}'", query);
// See if the index version exists and check if it matches.
String indexName = query.getSite().getIdentifier();
SearchRequestBuilder requestBuilder = new SearchRequestBuilder(nodeClient);
requestBuilder.setIndices(indexName);
requestBuilder.setSearchType(SearchType.QUERY_THEN_FETCH);
requestBuilder.setPreference("_local");
// Create the actual search query
QueryBuilder queryBuilder = new ElasticSearchSearchQuery(query);
requestBuilder.setQuery(queryBuilder);
logger.debug("Searching for {}", requestBuilder.toString());
// Make sure all fields are being returned
if (query.getFields().length > 0) {
requestBuilder.addFields(query.getFields());
requestBuilder.addField(IndexSchema.RESOURCE_ID);
requestBuilder.addField(IndexSchema.PATH);
requestBuilder.addField(IndexSchema.VERSION);
} else {
requestBuilder.addField("*");
}
// Restrict the scope to the given type
if (query.getTypes().length > 0) {
requestBuilder.setTypes(query.getTypes());
} else {
requestBuilder.setTypes(FileResource.TYPE, ImageResource.TYPE, MovieResource.TYPE, Page.TYPE);
}
// Pagination
if (query.getOffset() >= 0)
requestBuilder.setFrom(query.getOffset());
if (query.getLimit() >= 0)
requestBuilder.setSize(query.getLimit());
// Order by publishing date
if (!SearchQuery.Order.None.equals(query.getPublishingDateSortOrder())) {
switch (query.getPublishingDateSortOrder()) {
case Ascending:
requestBuilder.addSort(IndexSchema.PUBLISHED_FROM, SortOrder.ASC);
break;
case Descending:
requestBuilder.addSort(IndexSchema.PUBLISHED_FROM, SortOrder.DESC);
break;
case None:
default:
break;
}
}
// Order by modification date
else if (!SearchQuery.Order.None.equals(query.getModificationDateSortOrder())) {
switch (query.getModificationDateSortOrder()) {
case Ascending:
requestBuilder.addSort(IndexSchema.MODIFIED, SortOrder.ASC);
break;
case Descending:
requestBuilder.addSort(IndexSchema.MODIFIED, SortOrder.DESC);
break;
case None:
default:
break;
}
}
// Order by creation date
else if (!SearchQuery.Order.None.equals(query.getCreationDateSortOrder())) {
switch (query.getCreationDateSortOrder()) {
case Ascending:
requestBuilder.addSort(IndexSchema.CREATED, SortOrder.ASC);
break;
case Descending:
requestBuilder.addSort(IndexSchema.CREATED, SortOrder.DESC);
break;
case None:
default:
break;
}
}
// Order by score
// TODO: Order by score
// else {
// requestBuilder.addSort(IndexSchema.SCORE, SortOrder.DESC);
// }
try {
// Execute the query and try to get hold of a query response
SearchResponse response = null;
try {
response = nodeClient.search(requestBuilder.request()).actionGet();
} catch (Throwable t) {
throw new ContentRepositoryException(t);
}
// Create and configure the query result
long hits = response.getHits().getTotalHits();
long size = response.getHits().getHits().length;
SearchResultImpl result = new SearchResultImpl(query, hits, size);
result.setSearchTime(response.getTookInMillis());
// Walk through response and create new items with title, creator, etc:
for (SearchHit doc : response.getHits()) {
// Get the resource serializer
String type = doc.getType();
ResourceSerializer<?, ?> serializer = resourceSerializer.getSerializerByType(type);
if (serializer == null) {
logger.warn("Skipping search result due to missing serializer of type {}", type);
size--;
continue;
}
// Wrap the search result metadata
List<ResourceMetadata<?>> metadata = new ArrayList<ResourceMetadata<?>>(doc.getFields().size());
for (SearchHitField field : doc.getFields().values()) {
String name = field.getName();
ResourceMetadata<Object> m = new ResourceMetadataImpl<Object>(name);
// TODO: Add values with more care (localized, correct type etc.)
if (field.getValues().size() > 1) {
for (Object v : field.getValues()) {
m.addValue(v);
}
} else {
m.addValue(field.getValue());
}
metadata.add(m);
}
// Get the score for this item
float score = doc.getScore();
// Have the serializer in charge create a type-specific search result
// item
try {
SearchResultItem item = serializer.toSearchResultItem(query.getSite(), score, metadata);
result.addResultItem(item);
} catch (Throwable t) {
logger.warn("Error during search result serialization: '{}'. Skipping this search result.", t.getMessage());
size--;
continue;
}
}
result.setDocumentCount(size);
return result;
} catch (Throwable t) {
throw new ContentRepositoryException("Error querying index", t);
}
}