All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.blossomproject.ui.api.OmnisearchApiController Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
package com.blossomproject.ui.api;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.blossomproject.core.common.dto.AbstractDTO;
import com.blossomproject.core.common.search.SearchEngine;
import com.blossomproject.core.common.search.SearchResult;
import com.blossomproject.core.common.search.SummaryDTO;
import com.blossomproject.ui.stereotype.BlossomApiController;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.elasticsearch.action.search.MultiSearchRequestBuilder;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.TimeValue;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@BlossomApiController
@RequestMapping("/search")
public class OmnisearchApiController {

  private final Client client;
  private final PluginRegistry> registry;

  public OmnisearchApiController(Client client,
    PluginRegistry> registry) {
    this.client = client;
    this.registry = registry;
  }

  @GetMapping
  public Map omniSearch(
    @RequestParam(value = "q", defaultValue = "", required = false) String query,
    @PageableDefault(size = 20) Pageable pageable) {
    List plugins = filteredPlugins();
    if (plugins.isEmpty()) {
      Map model = Maps.newHashMap();
      model.put("q", query);
      model.put("total", 0);
      model.put("duration", 0L);
      model.put("results", Maps.newHashMap());
      return model;
    }

    MultiSearchRequestBuilder request = client.prepareMultiSearch();
    plugins.forEach(engine -> request.add(engine.prepareSearch(query, pageable)));
    MultiSearchResponse response = request.get(TimeValue.timeValueSeconds(15));

    int index = 0;
    Map> results = Maps.newHashMap();

    List items = Lists.newArrayList(response.getResponses());
    for (MultiSearchResponse.Item item : items) {
      SearchResponse unitResponse = item.getResponse();
      SearchEngine searchEngine = plugins.get(index);
      SearchResult result = searchEngine.parseSummaryResults(unitResponse, pageable);
      results.put(searchEngine.getName(), result);
      index++;
    }

    Map model = Maps.newHashMap();
    model.put("q", query);
    model.put("total",
      results.values().stream().mapToLong(r -> r.getPage().getTotalElements()).sum());
    model.put("duration",
      results.values().stream().mapToLong(SearchResult::getDuration).max().getAsLong());
    model.put("results", results.entrySet().stream()
      .filter(e -> e.getValue().getPage().getTotalElements() != 0)
      .sorted(Comparator.comparing(
        (Entry> e) -> e.getValue().getPage().getTotalElements())
        .reversed())
      .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (u, v) -> {
        throw new IllegalStateException(String.format("Duplicate key %s", u));
      }, LinkedHashMap::new)));

    return model;
  }

  @VisibleForTesting
  List filteredPlugins() {
    return registry.getPlugins().stream().filter(SearchEngine::includeInOmnisearch)
      .collect(Collectors.toList());
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy