package org.molgenis.data.elasticsearch.request; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import org.molgenis.data.Entity; import org.molgenis.data.Query; import org.molgenis.data.Sort; import org.molgenis.data.Sort.Direction; import org.molgenis.data.UnknownAttributeException; import org.molgenis.data.elasticsearch.index.MappingsBuilder; import org.molgenis.data.meta.AttributeType; import org.molgenis.data.meta.model.Attribute; import org.molgenis.data.meta.model.EntityType; /** * Adds Sort to the SearchRequestBuilder object. * * @author erwin */ public class SortGenerator implements QueryPartGenerator { @Override public void generate(SearchRequestBuilder searchRequestBuilder, Query<Entity> query, EntityType entityType) { if (query.getSort() != null) { for (Sort.Order sort : query.getSort()) { String sortAttrName = sort.getAttr(); if (sortAttrName == null) throw new IllegalArgumentException("Sort property is null"); Direction sortDirection = sort.getDirection(); if (sortDirection == null) throw new IllegalArgumentException("Missing sort direction"); Attribute sortAttr = entityType.getAttribute(sortAttrName); if (sortAttr == null) throw new UnknownAttributeException(sortAttrName); String sortField = getSortField(sortAttr); SortOrder sortOrder = sortDirection == Direction.ASC ? SortOrder.ASC : SortOrder.DESC; FieldSortBuilder sortBuilder = SortBuilders.fieldSort(sortField).order(sortOrder).sortMode("min"); searchRequestBuilder.addSort(sortBuilder); } } } private String getSortField(Attribute attr) { String sortField; AttributeType dataType = attr.getDataType(); switch (dataType) { case BOOL: case DATE: case DATE_TIME: case DECIMAL: case INT: case LONG: // use indexed field for sorting sortField = attr.getName(); break; case EMAIL: case ENUM: case HTML: case HYPERLINK: case SCRIPT: case STRING: case TEXT: // use raw field for sorting sortField = new StringBuilder(attr.getName()).append('.').append(MappingsBuilder.FIELD_NOT_ANALYZED) .toString(); break; case CATEGORICAL: case CATEGORICAL_MREF: case MREF: case XREF: case FILE: // use nested field for sorting String refSortField = getSortField(attr.getRefEntity().getLabelAttribute()); sortField = new StringBuilder(attr.getName()).append('.').append(refSortField).toString(); break; case COMPOUND: throw new UnsupportedOperationException(); default: throw new RuntimeException("Unknown data type [" + dataType + "]"); } return sortField; } }