Package com.browseengine.bobo.api

Source Code of com.browseengine.bobo.api.MultiBoboBrowser$BrowseFacetValueComparator

package com.browseengine.bobo.api;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.similarities.Similarity;

import com.browseengine.bobo.facets.FacetHandler;
import com.browseengine.bobo.sort.SortCollector;

/**
* Provides implementation of Browser for multiple Browser instances
*/
public class MultiBoboBrowser extends MultiReader implements Browsable {
  private static Logger logger = Logger.getLogger(MultiBoboBrowser.class);

  private IndexSearcher _indexSearcher = null;
  protected Browsable[] _subBrowsers;

  public MultiBoboBrowser(BoboMultiReader reader) throws IOException {
    this(reader._subReaders);
  }

  public MultiBoboBrowser(List<BoboSegmentReader> segmentReaders) throws IOException {
    super(segmentReaders.toArray(new BoboSegmentReader[0]), false);
    _indexSearcher = new IndexSearcher(this);
    initSubBrowsers();
  }

  /**
   *
   * @param browsers
   *          Browsers to search on
   * @throws IOException
   */
  public MultiBoboBrowser(Browsable[] browsers) throws IOException {
    super(getSubReaders(browsers), false);
    _indexSearcher = new IndexSearcher(this);
    initSubBrowsers();
  }

  public void initSubBrowsers() {
    List<AtomicReaderContext> leaves = getContext().leaves();
    _subBrowsers = new BoboSubBrowser[leaves.size()];
    for (int i = 0; i < leaves.size(); ++i) {
      _subBrowsers[i] = new BoboSubBrowser(leaves.get(i));
    }
  }

  private static IndexReader[] getSubReaders(Browsable[] browsers) {
    IndexReader[] readers = new IndexReader[browsers.length];
    for (int i = 0; i < browsers.length; ++i) {
      readers[i] = browsers[i].getIndexReader();
    }
    return readers;
  }

  public void browse(BrowseRequest req, final Collector hc, Map<String, FacetAccessible> facetMap)
      throws BrowseException {
    Weight w = null;
    try {
      Query q = req.getQuery();
      MatchAllDocsQuery matchAllDocsQuery = new MatchAllDocsQuery();
      if (q == null) {
        q = matchAllDocsQuery;
      } else if (!(q instanceof MatchAllDocsQuery)) {
        // MatchAllQuery is needed to filter out the deleted docids, that reside in
        // ZoieSegmentReader and are not visible on Bobo level
        matchAllDocsQuery.setBoost(0f);
        q = QueriesSupport.combineAnd(matchAllDocsQuery, q);
      }
      req.setQuery(q);
      w = _indexSearcher.createNormalizedWeight(q);
    } catch (Exception ioe) {
      throw new BrowseException(ioe.getMessage(), ioe);
    }
    browse(req, w, hc, facetMap, 0);
  }

  @Override
  public void browse(BrowseRequest req, Weight w, final Collector hc,
      Map<String, FacetAccessible> facetMap, int start) throws BrowseException {
    // index empty
    if (_subBrowsers == null || _subBrowsers.length == 0) {
      return;
    }

    Map<String, List<FacetAccessible>> mergedMap = new HashMap<String, List<FacetAccessible>>();
    try {
      Map<String, FacetAccessible> facetColMap = new HashMap<String, FacetAccessible>();
      for (int i = 0; i < _subBrowsers.length; i++) {
        try {
          _subBrowsers[i].browse(req, w, hc, facetColMap, (start + readerBase(i)));
        } finally {
          Set<Entry<String, FacetAccessible>> entries = facetColMap.entrySet();
          for (Entry<String, FacetAccessible> entry : entries) {
            String name = entry.getKey();
            FacetAccessible facetAccessor = entry.getValue();
            List<FacetAccessible> list = mergedMap.get(name);
            if (list == null) {
              list = new ArrayList<FacetAccessible>(_subBrowsers.length);
              mergedMap.put(name, list);
            }
            list.add(facetAccessor);
          }
          facetColMap.clear();
        }
      }
    } finally {
      if (req.getMapReduceWrapper() != null) {
        req.getMapReduceWrapper().finalizePartition();
      }
      Set<Entry<String, List<FacetAccessible>>> entries = mergedMap.entrySet();
      for (Entry<String, List<FacetAccessible>> entry : entries) {
        String name = entry.getKey();
        FacetHandler<?> handler = getFacetHandler(name);
        try {
          List<FacetAccessible> subList = entry.getValue();
          if (subList != null) {
            FacetAccessible merged = handler.merge(req.getFacetSpec(name), subList);
            facetMap.put(name, merged);
          }
        } catch (Exception e) {
          logger.error(e.getMessage(), e);
        }
      }
    }
  }

  /**
   * Generate a merged BrowseResult from the given BrowseRequest
   * @param req
   *          BrowseRequest for generating the facets
   * @return BrowseResult of the results of the BrowseRequest
   */
  @Override
  public BrowseResult browse(BrowseRequest req) throws BrowseException {

    final BrowseResult result = new BrowseResult();

    // index empty
    if (_subBrowsers == null || _subBrowsers.length == 0) {
      return result;
    }
    long start = System.currentTimeMillis();
    int offset = req.getOffset();
    int count = req.getCount();

    if (offset < 0 || count < 0) {
      throw new IllegalArgumentException("both offset and count must be > 0: " + offset + "/"
          + count);
    }
    SortCollector collector = getSortCollector(req.getSort(), req.getQuery(), offset, count,
      req.isFetchStoredFields(), req.getTermVectorsToFetch(), req.getGroupBy(),
      req.getMaxPerGroup(), req.getCollectDocIdCache());

    Map<String, FacetAccessible> facetCollectors = new HashMap<String, FacetAccessible>();
    browse(req, collector, facetCollectors);
    if (req.getMapReduceWrapper() != null) {
      result.setMapReduceResult(req.getMapReduceWrapper().getResult());
    }
    BrowseHit[] hits = null;
    try {
      hits = collector.topDocs();
    } catch (IOException e) {
      logger.error(e.getMessage(), e);
      result.addError(e.getMessage());
      hits = new BrowseHit[0];
    }

    Query q = req.getQuery();
    if (req.isShowExplanation()) {
      for (BrowseHit hit : hits) {
        try {
          int doc = hit.getDocid();
          Explanation expl = _indexSearcher.explain(q, doc);
          hit.setExplanation(expl);
        } catch (IOException e) {
          logger.error(e.getMessage(), e);
          result.addError(e.getMessage());
        }
      }
    }

    result.setHits(hits);
    result.setNumHits(collector.getTotalHits());
    result.setNumGroups(collector.getTotalGroups());
    result.setGroupAccessibles(collector.getGroupAccessibles());
    result.setSortCollector(collector);
    result.setTotalDocs(numDocs());
    result.addAll(facetCollectors);
    long end = System.currentTimeMillis();
    result.setTime(end - start);
    // set the transaction ID to trace transactions
    result.setTid(req.getTid());
    return result;
  }

  /**
   * Return the values of a field for the given doc
   *
   */
  @Override
  public String[] getFieldVal(int docid, final String fieldname) throws IOException {
    int i = readerIndex(docid);
    Browsable browser = _subBrowsers[i];
    return browser.getFieldVal(docid - readerBase(i), fieldname);
  }

  @Override
  public Object[] getRawFieldVal(int docid, String fieldname) throws IOException {
    int i = readerIndex(docid);
    Browsable browser = _subBrowsers[i];
    return browser.getRawFieldVal(docid - readerBase(i), fieldname);
  }

  /**
   * Compare BrowseFacets by their value
   */
  public static class BrowseFacetValueComparator implements Comparator<BrowseFacet> {
    @Override
    public int compare(BrowseFacet o1, BrowseFacet o2) {
      return o1.getValue().compareTo(o2.getValue());
    }
  }

  /**
   * Gets the sub-browser for a given docid
   *
   * @param docid
   * @return sub-browser instance
   */
  public Browsable subBrowser(int docid) {
    int i = readerIndex(docid);
    return _subBrowsers[i];
  }

  @Override
  public Set<String> getFacetNames() {
    Set<String> names = new HashSet<String>();
    for (Browsable subBrowser : _subBrowsers) {
      names.addAll(subBrowser.getFacetNames());
    }
    return names;
  }

  @Override
  public FacetHandler<?> getFacetHandler(String name) {
    for (Browsable subBrowser : _subBrowsers) {
      FacetHandler<?> subHandler = subBrowser.getFacetHandler(name);
      if (subHandler != null) {
        return subHandler;
      }
    }
    return null;
  }

  @Override
  public Map<String, FacetHandler<?>> getFacetHandlerMap() {
    HashMap<String, FacetHandler<?>> map = new HashMap<String, FacetHandler<?>>();
    for (Browsable subBrowser : _subBrowsers) {
      map.putAll(subBrowser.getFacetHandlerMap());
    }
    return map;
  }

  @Override
  public void setFacetHandler(FacetHandler<?> facetHandler) throws IOException {
    for (Browsable subBrowser : _subBrowsers) {
      subBrowser.setFacetHandler(facetHandler);
    }
  }

  @Override
  public SortCollector getSortCollector(SortField[] sort, Query q, int offset, int count,
      boolean fetchStoredFields, Set<String> termVectorsToFetch, String[] groupBy, int maxPerGroup,
      boolean collectDocIdCache) {
    if (_subBrowsers.length == 1) {
      return _subBrowsers[0].getSortCollector(sort, q, offset, count, fetchStoredFields,
        termVectorsToFetch, groupBy, maxPerGroup, collectDocIdCache);
    }
    return SortCollector.buildSortCollector(this, q, sort, offset, count, fetchStoredFields,
      termVectorsToFetch, groupBy, maxPerGroup, collectDocIdCache);
  }

  @Override
  public void doClose() throws IOException {
    super.doClose();
    for (Browsable subBrowser : _subBrowsers) {
      subBrowser.doClose();
    }
  }

  @Override
  public IndexReader getIndexReader() {
    return this;
  }

  public void setSimilarity(Similarity similarity) {
    if (similarity != null)
      _indexSearcher.setSimilarity(similarity);
  }
}
TOP

Related Classes of com.browseengine.bobo.api.MultiBoboBrowser$BrowseFacetValueComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.