lucene 多路归并算法

来源:互联网 发布:中国电视剧 国外 知乎 编辑:程序博客网 时间:2024/06/05 18:02

对于分布式存储的数据库(如elasticsearch),在执行完一次查询后,需要将多个节点的数据归并到一起(每个节点的数据已经排好序),这个时候需要使用到多路归并算法,下面以lucene的实现代码为例子讲解。

1、每个数据节点上的数据作为一个TopDocs,那么多个数据节点上的topDocs组成一个TopDocs[]

2、将TopDocs[]添加到一个最大堆中,堆中的每个节点对应一个topDocs,堆中每个节点大小的比较标准以每个topdocs中的hitIndex指针指向的doc的分数为标准。
3、将最大堆的根节点移除出来作为一个topDocs,该topDocs中的hitIndex指针指向的doc肯定是最大的,将该doc放入到返回结果的数组中。hitIndex是否已经遍历完该topDocs,如果没有遍历完,需要将该topDocs重新加回到最大堆中
4、判断堆中是否还有节点,如果有,继续第3步


详细代码
public static TopDocs merge(Sort sort, int start, int size, TopDocs[] shardHits) throws IOException {
    final PriorityQueue<ShardRef> queue;
    if (sort == null) {
      //构造最大堆       
      queue = new ScoreMergeSortQueue(shardHits);
    } else {
      queue = new MergeSortQueue(sort, shardHits);
    }


    int totalHitCount = 0;
    int availHitCount = 0;
    float maxScore = Float.MIN_VALUE;
    for(int shardIDX=0;shardIDX<shardHits.length;shardIDX++) {
      final TopDocs shard = shardHits[shardIDX];
      // totalHits can be non-zero even if no hits were
      // collected, when searchAfter was used:
      totalHitCount += shard.totalHits;
      if (shard.scoreDocs != null && shard.scoreDocs.length > 0) {
        availHitCount += shard.scoreDocs.length;
        //将TopDocs[] 中的topDocs逐个添加到最大堆中,判断大小的标准是topDocs中hitIndex指向的doc的分数大小        
        queue.add(new ShardRef(shardIDX));
        maxScore = Math.max(maxScore, shard.getMaxScore());
        //System.out.println("  maxScore now " + maxScore + " vs " + shard.getMaxScore());
      }
    }

    if (availHitCount == 0) {

      maxScore = Float.NaN;
    }

    final ScoreDoc[] hits;

    if (availHitCount <= start) {
      hits = new ScoreDoc[0];
    } else {
      hits = new ScoreDoc[Math.min(size, availHitCount - start)];
      int requestedResultWindow = start + size;
      int numIterOnHits = Math.min(availHitCount, requestedResultWindow);
      int hitUpto = 0;
      while (hitUpto < numIterOnHits) {
        assert queue.size() > 0;
        //获取最大堆中的根节点        
        ShardRef ref = queue.pop();
        //拿到最大的doc,放入到hits中
        final ScoreDoc hit = shardHits[ref.shardIndex].scoreDocs[ref.hitIndex++];
        hit.shardIndex = ref.shardIndex;
        //如果达到了start后,才放入到hits(分页)
        if (hitUpto >= start) {
          hits[hitUpto - start] = hit;
        }
        hitUpto++;

        if (ref.hitIndex < shardHits[ref.shardIndex].scoreDocs.length) {
           
          queue.add(ref);
        }
      }
    }

    if (sort == null) {
      return new TopDocs(totalHitCount, hits, maxScore);
    } else {
      return new TopFieldDocs(totalHitCount, hits, sort.getSort(), maxScore);
    }
  }




  //最大堆中各节点判断大小的标准
  @Override
    public boolean lessThan(ShardRef first, ShardRef second) {
      assert first != second;
      //每个节点上hitIndex指向的doc的score
      final float firstScore = shardHits[first.shardIndex][first.hitIndex].score;
      final float secondScore = shardHits[second.shardIndex][second.hitIndex].score;
      if (firstScore < secondScore) {
        return false;
      } else if (firstScore > secondScore) {
        return true;
      } else {
        // Tie break: earlier shard wins
        if (first.shardIndex < second.shardIndex) {
          return true;
        } else if (first.shardIndex > second.shardIndex) {
          return false;
        } else {
          // Tie break in same shard: resolve however the
          // shard had resolved it:
          assert first.hitIndex != second.hitIndex;
          return first.hitIndex < second.hitIndex;
        }
      }
    }
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 包包的铆钉坏了怎么办 汽车半轴螺丝母拧不动怎么办? 卫衣袖子短了怎么办 u型导轨蚊帐下垂怎么办 100的水管螺纹出漏水怎么办 吊顶螺丝没有防锈处理怎么办 膨胀螺丝洞松了怎么办 膨胀螺丝眼大了怎么办 墙上螺丝孔大了怎么办 膨胀螺丝孔深了怎么办 克霉膨胀栓的线怎么办 摩托车排气管螺丝断了怎么办 汽车轮胎螺丝卸不下来怎么办 内六角螺丝卸不下来怎么办 洗衣机六角螺丝卸不动怎么办 黄油嘴打不进去怎么办 螺杆冷水机氟系统有空气怎么办 脚踏式加油枪皮碗不下去怎么办? 自攻螺丝滑丝怎么办? 大工打小工老板不管怎么办 虾缸的过滤吸虾怎么办 加热棒坏了鱼怎么办 钢材软打孔断钻头怎么办 空调余额下水管检查口按不上怎么办 风机盘管噪音大怎么办 混凝土水泥放少了怎么办 门式钢梁端板连接下料短啦怎么办? 灌桩导管堵了怎么办 公路车尾钩歪了怎么办 铃木羚羊车大灯不亮怎么办 玻璃瓶打碎了里面食物怎么办 玻璃门上轴坏了怎么办 配筋面积小了怎么办 ps大文件存不了怎么办 挑架钢丝绳拉环未预埋怎么办 出现偏拉的梁怎么办 尾插不好上锡怎么办 汽车玻璃上的焊点很难去除怎么办 拆苹果硬盘焊点掉了怎么办 玻璃被电焊滴到怎么办 gta5特质卡宾装了消音器怎么办