Github user nickwallen commented on a diff in the pull request:
https://github.com/apache/metron/pull/832#discussion_r149182933
--- Diff:
metron-platform/metron-elasticsearch/src/main/java/org/apache/metron/elasticsearch/dao/ElasticsearchDao.java
---
@@ -98,78 +121,153 @@ public ElasticsearchDao() {
//uninitialized.
}
- private static Map<String, FieldType> elasticsearchSearchTypeMap;
-
- static {
- Map<String, FieldType> fieldTypeMap = new HashMap<>();
- fieldTypeMap.put("string", FieldType.STRING);
- fieldTypeMap.put("ip", FieldType.IP);
- fieldTypeMap.put("integer", FieldType.INTEGER);
- fieldTypeMap.put("long", FieldType.LONG);
- fieldTypeMap.put("date", FieldType.DATE);
- fieldTypeMap.put("float", FieldType.FLOAT);
- fieldTypeMap.put("double", FieldType.DOUBLE);
- fieldTypeMap.put("boolean", FieldType.BOOLEAN);
- elasticsearchSearchTypeMap = Collections.unmodifiableMap(fieldTypeMap);
- }
-
@Override
public SearchResponse search(SearchRequest searchRequest) throws
InvalidSearchException {
return search(searchRequest, new
QueryStringQueryBuilder(searchRequest.getQuery()));
}
/**
* Defers to a provided {@link
org.elasticsearch.index.query.QueryBuilder} for the query.
- * @param searchRequest The request defining the parameters of the search
+ * @param request The request defining the parameters of the search
* @param queryBuilder The actual query to be run. Intended for if the
SearchRequest requires wrapping
* @return The results of the query
* @throws InvalidSearchException When the query is malformed or the
current state doesn't allow search
*/
- protected SearchResponse search(SearchRequest searchRequest,
QueryBuilder queryBuilder) throws InvalidSearchException {
+ protected SearchResponse search(SearchRequest request, QueryBuilder
queryBuilder) throws InvalidSearchException {
+ org.elasticsearch.action.search.SearchRequest esRequest;
+ org.elasticsearch.action.search.SearchResponse esResponse;
+
if(client == null) {
throw new InvalidSearchException("Uninitialized Dao! You must call
init() prior to use.");
}
- if (searchRequest.getSize() > accessConfig.getMaxSearchResults()) {
+
+ if (request.getSize() > accessConfig.getMaxSearchResults()) {
throw new InvalidSearchException("Search result size must be less
than " + accessConfig.getMaxSearchResults());
}
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
+
+ esRequest = buildSearchRequest(request, queryBuilder);
+ esResponse = searchSubmitter.submitSearch(esRequest);
+ return buildSearchResponse(request, esResponse);
+ }
+
+ /**
+ * Builds an Elasticsearch search request.
+ * @param searchRequest The Metron search request.
+ * @param queryBuilder
+ * @return An Elasticsearch search request.
+ */
+ private org.elasticsearch.action.search.SearchRequest buildSearchRequest(
+ SearchRequest searchRequest,
+ QueryBuilder queryBuilder) throws InvalidSearchException {
+
+ LOG.debug("Got search request; request={}",
ElasticsearchUtils.toJSON(searchRequest));
+ SearchSourceBuilder searchBuilder = new SearchSourceBuilder()
.size(searchRequest.getSize())
.from(searchRequest.getFrom())
.query(queryBuilder)
.trackScores(true);
- searchRequest.getSort().forEach(sortField ->
searchSourceBuilder.sort(sortField.getField(),
getElasticsearchSortOrder(sortField.getSortOrder())));
- Optional<List<String>> fields = searchRequest.getFields();
- if (fields.isPresent()) {
- searchSourceBuilder.fields(fields.get());
- } else {
- searchSourceBuilder.fetchSource(true);
+
+ // column metadata needed to understand the type of each sort field
+ Map<String, Map<String, FieldType>> meta;
+ try {
+ meta = getColumnMetadata(searchRequest.getIndices());
+ } catch(IOException e) {
+ throw new InvalidSearchException("Unable to get column metadata", e);
}
- Optional<List<String>> facetFields = searchRequest.getFacetFields();
- if (facetFields.isPresent()) {
- facetFields.get().forEach(field ->
searchSourceBuilder.aggregation(new
TermsBuilder(getFacentAggregationName(field)).field(field)));
+
+ // handle sort fields
+ for(SortField sortField : searchRequest.getSort()) {
+
+ // what type is the sort field?
+ FieldType sortFieldType = meta
+ .values()
+ .stream()
+ .filter(e -> e.containsKey(sortField.getField()))
+ .map(m -> m.get(sortField.getField()))
+ .findFirst()
+ .orElse(FieldType.OTHER);
+
+ // sort order - if ASC, then missing values sorted last. Otherwise,
missing values sorted first
+ org.elasticsearch.search.sort.SortOrder sortOrder =
getElasticsearchSortOrder(sortField.getSortOrder());
+ String missingSortOrder;
+ if(sortOrder == org.elasticsearch.search.sort.SortOrder.DESC) {
+ missingSortOrder = SORT_MISSING_LAST;
+ } else {
+ missingSortOrder = SORT_MISSING_FIRST;
+ }
--- End diff --
Here is the additional logic to handle sorting of 'missing' fields.
---