读书人

Bobo源码札记4(collector的创建)

发布时间: 2012-09-20 09:36:50 作者: rapoo

Bobo源码笔记4(collector的创建)

Bobo的收集器基类是SortCollector继承于lucene的Collector类,其中函数是获取收集器的外部接口:

?

public static SortCollector buildSortCollector(Browsable browser,Query q,SortField[] sort,int offset,int count,boolean forceScoring,boolean fetchStoredFields){boolean doScoring=forceScoring;if (sort == null || sort.length==0){if (q!=null && !(q instanceof MatchAllDocsQuery)){  sort = new SortField[]{SortField.FIELD_SCORE};}}if (sort==null || sort.length==0){sort = new SortField[]{SortField.FIELD_DOC};}Set<String> facetNames = browser.getFacetNames();for (SortField sf : sort){if (sf.getType() == SortField.SCORE) {doScoring= true;break;}}DocComparatorSource compSource;if (sort.length==1){                        //对sort[]记性转换                       ?SortField sf = convert(browser,sort[0]);compSource = getComparatorSource(browser,sf);}else{DocComparatorSource[] compSources = new DocComparatorSource[sort.length];for (int i = 0; i<sort.length;++i){compSources[i]=getComparatorSource(browser,convert(browser,sort[i]));}                        //可以对结果以多个field进行排序,排序的优先级由sort[]中的位置确定,例:sort[0]优先于sort[1]?                       compSource = new MultiDocIdComparatorSource(compSources);}return new SortCollectorImpl(compSource, sort, browser, offset, count, doScoring, fetchStoredFields);}

?

其中convert(browsable , sortField[])函数是对sortField进行转换,如果有该field的facetHandler,那么就必须使用该facetHandler自定义的Comparator(比较器)进行收集(collect):

?

private static SortField convert(Browsable browser,SortField sort){String field =sort.getField();FacetHandler<?> facetHandler = browser.getFacetHandler(field);if (facetHandler!=null){                        //有该sortField所在域的FacetHandler的时候使用facet自己的ComparatorBoboCustomSortField sortField = new BoboCustomSortField(field, sort.getReverse(), facetHandler.getDocComparatorSource());return sortField;}else{return sort;}}
?

上面的转换的影响从下边函数里可以体现出来,上面有facet的SortField被转换成BoboCustomSortField,在下面函数中

 if (sf instanceof BoboCustomSortField){BoboCustomSortField custField = (BoboCustomSortField)sf;DocComparatorSource src = custField.getCustomComparatorSource();assert src!=null;compSource = src;}

使用了facetHandler的比较器的产生器来生产Comparator

?

?

private static DocComparatorSource getComparatorSource(Browsable browser,SortField sf){DocComparatorSource compSource = null;//按照文档的id进行排序收集                if (SortField.FIELD_DOC.equals(sf)){compSource = new DocIdDocComparatorSource();}//按照文档的得分进行收集               ?else if (SortField.FIELD_SCORE.equals(sf) || sf.getType() == SortField.SCORE){// we want to do reverse sorting regardless for relevancecompSource = new ReverseDocComparatorSource(new RelevanceDocComparatorSource());}else if (sf instanceof BoboCustomSortField){BoboCustomSortField custField = (BoboCustomSortField)sf;DocComparatorSource src = custField.getCustomComparatorSource();assert src!=null;compSource = src;}else{Set<String> facetNames = browser.getFacetNames();String sortName = sf.getField();if (facetNames.contains(sortName)){FacetHandler<?> handler = browser.getFacetHandler(sortName);assert handler!=null;compSource = handler.getDocComparatorSource();}else{// default lucene fieldcompSource = getNonFacetComparatorSource(sf);}}boolean reverse = sf.getReverse();if (reverse){compSource = new ReverseDocComparatorSource(compSource);}compSource.setReverse(reverse);return compSource;}

?

SortCollectorImpl是sortCollector类的一个实现类,实现Collector类的接口SetNextReader()函数:

?

 @Override  public void setNextReader(IndexReader reader, int docBase) throws IOException {    assert reader instanceof BoboIndexReader;    _currentReader = (BoboIndexReader)reader;   //得到当前Reader下的比较器   ?_currentComparator = _compSource.getComparator(reader,docBase);    //用于收集当前Reader搜索结果的最小堆,用上面的比较器    _currentQueue = new DocIDPriorityQueue(_currentComparator, _numHits, docBase);    MyScoreDoc myScoreDoc = (MyScoreDoc)_tmpScoreDoc;    myScoreDoc.queue = _currentQueue;    myScoreDoc.reader = _currentReader;    myScoreDoc.sortValue = null;    _pqList.add(_currentQueue);    _queueFull = false;  }
?

?最后对多个IndexReader的结果进行merge(合并)

?

 @Override  public BrowseHit[] topDocs() throws IOException{    ArrayList<Iterator<MyScoreDoc>> iterList = new ArrayList<Iterator<MyScoreDoc>>(_pqList.size());    for (DocIDPriorityQueue pq : _pqList){      int count = pq.size();      MyScoreDoc[] resList = new MyScoreDoc[count];      for (int i = count - 1; i >= 0; i--) {         resList[i] = (MyScoreDoc)pq.pop();      }       //将每个IndexReader的结果从最小堆转移到List中,将每个List的iterator添加到一个List<iterator>中去       iterList.add(Arrays.asList(resList).iterator());    }   //对多个IndexReader的搜索结果队列进行多路归并    ArrayList<MyScoreDoc> resList = ListMerger.mergeLists(_offset, _count, iterList, MERGE_COMPATATOR);    Map<String,FacetHandler<?>> facetHandlerMap = _boboBrowser.getFacetHandlerMap();    return buildHits(resList.toArray(new MyScoreDoc[resList.size()]), _sortFields, facetHandlerMap, _fetchStoredFields);  }  //将搜索结果转换成BrowseHit  protected static BrowseHit[] buildHits(MyScoreDoc[] scoreDocs,SortField[] sortFields,Map<String,FacetHandler<?>> facetHandlerMap,boolean fetchStoredFields)  throws IOException  {    BrowseHit[] hits = new BrowseHit[scoreDocs.length];    Collection<FacetHandler<?>> facetHandlers= facetHandlerMap.values();    for (int i =scoreDocs.length-1; i >=0 ; i--)    {      MyScoreDoc fdoc = scoreDocs[i];      BoboIndexReader reader = fdoc.reader;      BrowseHit hit=new BrowseHit();      if (fetchStoredFields){        hit.setStoredFields(reader.document(fdoc.doc));      }      Map<String,String[]> map = new HashMap<String,String[]>();      Map<String,Object[]> rawMap = new HashMap<String,Object[]>();      for (FacetHandler<?> facetHandler : facetHandlers)      {          map.put(facetHandler.getName(),facetHandler.getFieldValues(reader,fdoc.doc));          rawMap.put(facetHandler.getName(),facetHandler.getRawFieldValues(reader,fdoc.doc));      }      hit.setFieldValues(map);      hit.setRawFieldValues(rawMap);      hit.setDocid(fdoc.doc+fdoc.queue.base);      hit.setScore(fdoc.score);      hit.setComparable(fdoc.getValue());      hits[i] = hit;    }    return hits;  }
?

?

?

?

?

读书人网 >开源软件

热点推荐