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

com.blossomproject.ui.web.OmnisearchController Maven / Gradle / Ivy

package com.blossomproject.ui.web;

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.BlossomController;
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.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@BlossomController
@RequestMapping("/search")
public class OmnisearchController {

  private final Client client;
  private final PluginRegistry> registry;

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

  @GetMapping
  public ModelAndView omniSearch(
    @RequestParam(value = "q", defaultValue = "", required = false) String query,
    @PageableDefault(size = 20) Pageable pageable,
    Model model) {
    List plugins = filteredPlugins();
    if(plugins.isEmpty()){
      return new ModelAndView("omnisearch/omnisearch", model.asMap());
    }

    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++;
    }

    model.addAttribute("q", query);
    model.addAttribute("total",
      results.values().stream().mapToLong(r -> r.getPage().getTotalElements()).sum());
    model.addAttribute("duration",
      results.values().stream().mapToLong(SearchResult::getDuration).max().getAsLong());
    model.addAttribute("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 new ModelAndView("blossom/omnisearch/omnisearch", model.asMap());
  }

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy