0

段内排序IndexSort

 3 years ago
source link: https://www.amazingkoala.com.cn/Lucene/Index/2021/0915/201.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

段内排序IndexSort(Lucene 8.9.0)

  段内排序IndexSort是Lucene在索引(Indexing)阶段提供的一个功能,该功能使得在执行flushcommit或者NRT操作后,新生成的段其包含的文档是有序的,即在索引阶段实现了文档的排序。

  在之前的一些文章中已经简单的介绍了IndexSort,例如在文章构造IndexWriter对象(一) 说到,通过在IndexWriter的配置信息中添加IndexSort信息来开启段内排序的功能;在文章文档提交之flush(三)中提到了对文档进行段内排序的时机点;在文章Collector(三)中提到了在Search阶段,如何通过IndexSort实现高效(提前结束)收集满足查询条件的文档集合。

  本系列文章将会详细介绍IndexSort在索引阶段相关的内容,以及它将如何影响索引文件的生成、段的合并、以及在查询阶段的用途。

IndexSort的应用

  我们先通过一个例子来了解如何使用IndexSort这个功能。完整的demo地址见:https://github.com/LuXugang/Lucene-7.5.0/blob/master/LuceneDemo8.9.0/src/main/java/index/IndexSortTest.java

1.png

2.png

  图1中的第44、45行代码定义了两个排序规则。在继续展开介绍之前,我们先简单的说下Lucene中正排索引SortedSetDocValuesField(见图2)的一些概念。

SortedSetDocValuesField

  使用SortedSetDocValuesField可以使得我们在同一篇文档中定义一个或多个具有相同域名不同域值的SortedSetDocValuesField域。这种域的其中一个应用方式即在索引阶段,对于一篇文档,我们可以选择其包含的SortedSetDocValuesField域的某一个域值参与段内排序。

  例如在图2中,文档3中(代码第80、81行)定义了2个域名为"sort0",域值分别为"b1"、"b2"的SortedSetDocValuesField域。并且在图1中的第44行代码定义了一个段内排序规则,该规则描述的是每个文档会使用域名为"sort0",并且将最小的域值来参与排序。那么对于文档3,它将使用域值为"b1"(字符串使用字典序进行排序)参与段内排序。

SortedSetSelector.Type

  图2中SortedSetSelector.Type.MIN规定了使用最小的域值参与段内排序。SortedSetSelector.Type的所有选项如下所示:

3.png

  图3中MIN、MAX就不做介绍了,我们说下MIDDLE_MIN跟MIDDLE_MAX。

MIDDLE_MIN、MIDDLE_MAX

  如果域值的数量是奇数,那么MIDDLE_MIN、MIDDLE_MAX具有相同的作用,比如有以下的域值:

xxxxxxxxxx
{"b1", "b2", "b3", "b4", "b5"}

  那么将会选择"b3"参与排序。

  如果域值的数量是偶数,假设有以下的域值:

xxxxxxxxxx
{"b1", "b2", "b3", "b4", "b5", "b6"}

  那么在MIDDLE_MIN条件下会选择"b3"、在MIDDLE_MAX下会选择"b4"。

  另外使用SortedSetDocValuesField的一个场景是,我们在搜索阶段可以根据SortedSetDocValuesField对查询结果进行排序,并且可以通过指定不同的SortedSetSelector.Type获取不同的排序结果。

排序方式概述

  我们接着看下图1。图1中定义了两个规则,那么在段内排序的过程中,先按照"sort0"进行排序,当无法比较出先后关系时,接着按照"sort1"进行排序,如果两个排序规则都无法比较出先后关系,则最终比较文档的添加顺序。

文档之间的排序比较方式

4.png

5.png

  图4中,我们的搜索条件没有对结果增加额外的排序规则,那么查询结果将会按照段内排序后的顺序输出

  我们结合图2,分别介绍下一些文档之间排序比较的方式。

  这里说的文档0指的是图2中添加的顺序,如图2中第53行的代码所示。

  根据"sort0"的排序规则,将按照域值从大到小排序(SortedSetSortField的第二个参数reverse的值为true),所以文档0~3这四篇文档将分别使用"c1"、"b1"、"b1"、"b1"进行比较,另外由于文档4中没有"sort0"域,那么它将被排到最末位置。可见根据"sort0",只能确定文档0是排在最前面的以及文档4是排在最后面,如下所示。故需要通过"sort1"对文档1、2、3进一步排序。

xxxxxxxxxx
文档0 --> 文档1、2、3 --> 文档4

文档1、2、3

  根据"sort1"的排序规则,将按照域值从大到小排序,所以文档1、2、3这四篇文档将分别使用"e2"、"f2"、"e2"进行比较,可见文档2在这三篇文档中排在最前面,由于文档1、3无法通过"sort1"区分出先后关系,并且没有其他的排序排序规则了,那么由于文档1先被添加,故文档1排在文档3前面,如下所示:

xxxxxxxxxx
文档0 --> 文档2 --> 文档1 --> 文档3 --> 文档4

搜索阶段的排序

  上文中说到SortedSetDocValuesField可以用于在索引阶段排序,同样的它也可以用于搜索阶段的排序。在设置了图1中的排序规则前提下,如果我们在搜索阶段提供了以下的排序规则:

6.png

  其查询结果如下所示:

7.png

  其排序的比较过程跟IndexSort是一样的,这里就不赘述了。

用于排序的域

  下图中列出了其他可以用于段内排序的域:

8.png

  这些域的使用方法可以通过查看每个类的注释就可以完全理解,故不展开介绍了。

  下一篇文章中,我们将介绍段内排序在索引阶段的排序方式、排序时机点以及其他相关内容。

点击下载附件


Recommend

  • 184

    排序算法(Sort) 引言 我们平时对计算机中存储的数据执行的两种最常见的操作就是排序和查找,对于计算机的排序和查找的研究,自计算机诞生以来就没有停止过。如今又是大数据,云计算的时代,对数据的排序和查找的速度、效率要求更高,因此要对排序和查找的算法进...

  • 142
    • 微信 mp.weixin.qq.com 6 years ago
    • Cache

    爱奇艺个性化推荐排序实践

    爱奇艺个性化推荐排序实践 Original 爱奇艺...

  • 118
    • 掘金 juejin.im 6 years ago
    • Cache

    解读排序算法

    算法算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。 简单点说,算法就是解决问题的方法。确切来说它是相对于计算机程序的,大多数情况并不与具体某一种编程语言有关,但今天我们...

  • 96
    • 微信 mp.weixin.qq.com 6 years ago
    • Cache

    高级排序算法

  • 108

    小白学数据结构——四、排序算法Python(桶、计数、基数排序)

  • 86

    数据结构(十二)——排序算法一、排序简介1、排序的一般定义排序是计算机中经常进行的操作,目的在于将一组无序的数据元素调整为有序的数据元素。序列:1,20,45,5,2,12排序后:1,2,5,12,20,452、排序的数学定义3、排序的稳定性如果序列中的两个元素R[i]、...

  • 97
    • www.cnblogs.com 6 years ago
    • Cache

    八大排序算法Java实现 - morethink

  • 72

    插入排序的思想就和玩扑克是的摸牌一样,摸到一张牌放手上,再摸一张和之前的比较,大的就放后面,小的就放前面。一个数列我们把它分为两个区,一个是已经排序的区,一个是乱序区,选取第一个元素出来作为排序区的元素,然后从第二个元素开始往后作为乱序区,从第...

  • 72
    • 微信 mp.weixin.qq.com 6 years ago
    • Cache

    Java内存模型与指令重排序

  • 59
    • 掘金 juejin.im 6 years ago
    • Cache

    搞懂基本排序算法

    搞懂基本排序算法 上篇文章写了关于 Java 内部类的基本知识,感兴趣的朋友可以去看一下:搞懂 JAVA 内部类;本文写的内容是最近学习的算法相关知识中的基本排序算法,排序算法也算是面试中的常客了,实际上也是算法中最基本的知识。由于 Android 开发中用

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK