public String searchByQuery()

in core/src/main/java/org/apache/sdap/mudrod/driver/ESDriver.java [274:385]


  public String searchByQuery(String index, String type, String query, Boolean bDetail) throws IOException, InterruptedException, ExecutionException {
    boolean exists = getClient().admin().indices().prepareExists(index).execute().actionGet().isExists();
    if (!exists) {
      return null;
    }

    QueryBuilder qb = QueryBuilders.queryStringQuery(query);
    SearchResponse response = getClient().prepareSearch(index).setTypes(type).setQuery(qb).setSize(500).execute().actionGet();

    // Map of K,V pairs where key is the field name from search result and value is the that should be returned for that field. Not always the same.
    Map<String, String> fieldsToReturn = new HashMap<>();

    fieldsToReturn.put("Dataset-ShortName", "Short Name");
    fieldsToReturn.put("Dataset-LongName", "Long Name");
    fieldsToReturn.put("DatasetParameter-Topic", "Topic");
    fieldsToReturn.put("Dataset-Description", "Dataset-Description");
    fieldsToReturn.put("DatasetCitation-ReleaseDateLong", "Release Date");

    if (bDetail) {
      fieldsToReturn.put("DatasetPolicy-DataFormat", "DataFormat");
      fieldsToReturn.put("Dataset-Doi", "Dataset-Doi");
      fieldsToReturn.put("Dataset-ProcessingLevel", "Processing Level");
      fieldsToReturn.put("DatasetCitation-Version", "Version");
      fieldsToReturn.put("DatasetSource-Sensor-ShortName", "DatasetSource-Sensor-ShortName");
      fieldsToReturn.put("DatasetProject-Project-ShortName", "DatasetProject-Project-ShortName");
      fieldsToReturn.put("DatasetParameter-Category", "DatasetParameter-Category");
      fieldsToReturn.put("DatasetLocationPolicy-BasePath", "DatasetLocationPolicy-BasePath");
      fieldsToReturn.put("DatasetParameter-Variable-Full", "DatasetParameter-Variable-Full");
      fieldsToReturn.put("DatasetParameter-Term-Full", "DatasetParameter-Term-Full");
      fieldsToReturn.put("DatasetParameter-VariableDetail", "DatasetParameter-VariableDetail");

      fieldsToReturn.put("DatasetRegion-Region", "Region");
      fieldsToReturn.put("DatasetCoverage-NorthLat", "NorthLat");
      fieldsToReturn.put("DatasetCoverage-SouthLat", "SouthLat");
      fieldsToReturn.put("DatasetCoverage-WestLon", "WestLon");
      fieldsToReturn.put("DatasetCoverage-EastLon", "EastLon");
      fieldsToReturn.put("DatasetCoverage-StartTimeLong-Long", "DatasetCoverage-StartTimeLong-Long");
      fieldsToReturn.put("Dataset-DatasetCoverage-StopTimeLong", "Dataset-DatasetCoverage-StopTimeLong");

      fieldsToReturn.put("Dataset-TemporalResolution", "Dataset-TemporalResolution");
      fieldsToReturn.put("Dataset-TemporalRepeat", "Dataset-TemporalRepeat");
      fieldsToReturn.put("Dataset-LatitudeResolution", "Dataset-LatitudeResolution");
      fieldsToReturn.put("Dataset-LongitudeResolution", "Dataset-LongitudeResolution");
      fieldsToReturn.put("Dataset-AcrossTrackResolution", "Dataset-AcrossTrackResolution");
      fieldsToReturn.put("Dataset-AlongTrackResolution", "Dataset-AlongTrackResolution");
    }

    List<Map<String, Object>> searchResults = new ArrayList<>();

    for (SearchHit hit : response.getHits().getHits()) {
      Map<String, Object> source = hit.getSource();

      Map<String, Object> searchResult = source.entrySet().stream().filter(entry -> fieldsToReturn.keySet().contains(entry.getKey()))
          .collect(Collectors.toMap(entry -> fieldsToReturn.get(entry.getKey()), Entry::getValue));

      // searchResult is now a map where the key = value from fieldsToReturn and the value = value from search result

      // Some results require special handling/formatting:
      // Release Date formatting
      LocalDate releaseDate = Instant.ofEpochMilli(Long.parseLong(((ArrayList<String>) searchResult.get("Release Date")).get(0))).atZone(ZoneId.of("Z")).toLocalDate();
      searchResult.put("Release Date", releaseDate.format(DateTimeFormatter.ISO_DATE));

      if (bDetail) {

        // DataFormat value, translate RAW to BINARY
        if ("RAW".equals(searchResult.get("DataFormat"))) {
          searchResult.put("DataFormat", "BINARY");
        }

        // DatasetLocationPolicy-BasePath Should only contain ftp, http, or https URLs
        List<String> urls = ((List<String>) searchResult.get("DatasetLocationPolicy-BasePath")).stream().filter(url -> url.startsWith("ftp") || url.startsWith("http")).collect(Collectors.toList());
        searchResult.put("DatasetLocationPolicy-BasePath", urls);

        // Time Span Formatting
        LocalDate startDate = Instant.ofEpochMilli((Long) searchResult.get("DatasetCoverage-StartTimeLong-Long")).atZone(ZoneId.of("Z")).toLocalDate();
        LocalDate endDate = "".equals(searchResult.get("Dataset-DatasetCoverage-StopTimeLong")) ?
            null :
            Instant.ofEpochMilli(Long.parseLong(searchResult.get("Dataset-DatasetCoverage-StopTimeLong").toString())).atZone(ZoneId.of("Z")).toLocalDate();
        searchResult.put("Time Span", startDate.format(DateTimeFormatter.ISO_DATE) + " to " + (endDate == null ? "Present" : endDate.format(DateTimeFormatter.ISO_DATE)));

        // Temporal resolution can come from one of two fields
        searchResult.put("TemporalResolution", "".equals(searchResult.get("Dataset-TemporalResolution")) ? searchResult.get("Dataset-TemporalRepeat") : searchResult.get("Dataset-TemporalResolution"));

        // Special formatting for spatial resolution
        String latResolution = (String) searchResult.get("Dataset-LatitudeResolution");
        String lonResolution = (String) searchResult.get("Dataset-LongitudeResolution");
        if (!latResolution.isEmpty() && !lonResolution.isEmpty()) {
          searchResult.put("SpatialResolution", latResolution + " degrees (latitude) x " + lonResolution + " degrees (longitude)");
        } else {
          String acrossResolution = (String) searchResult.get("Dataset-AcrossTrackResolution");
          String alonResolution = (String) searchResult.get("Dataset-AlongTrackResolution");
          double dAcrossResolution = Double.parseDouble(acrossResolution) / 1000;
          double dAlonResolution = Double.parseDouble(alonResolution) / 1000;
          searchResult.put("SpatialResolution", dAlonResolution + " km (Along) x " + dAcrossResolution + " km (Across)");
        }

        // Measurement is a list of hierarchies that goes Topic -> Term -> Variable -> Variable Detail. Need to construct these hierarchies.
        List<List<String>> measurements = buildMeasurementHierarchies((List<String>) searchResult.get("Topic"), (List<String>) searchResult.get("DatasetParameter-Term-Full"),
            (List<String>) searchResult.get("DatasetParameter-Variable-Full"), (List<String>) searchResult.get("DatasetParameter-VariableDetail"));

        searchResult.put("Measurements", measurements);

      }

      searchResults.add(searchResult);
    }

    Map<String, List<?>> pdResults = new HashMap<>();
    pdResults.put("PDResults", searchResults);

    return new GsonBuilder().create().toJson(pdResults);
  }