如何在Lucene文档中定义主键字段以获得最佳的查找性能?

2024-02-07

在我的 Lucene 索引 (v7.2) 中创建文档时,我添加了uid包含唯一 id/key(字符串)的字段:

doc.add(new StringField("uid",uid,Field.Store.YES))

为了稍后检索该文档,我为给定的唯一 ID 创建一个 TermQuery 并使用 IndexSearcher 搜索它:

searcher.search(new TermQuery(new Term("uid",uid)),1)

作为一个Lucene“新手”,我想了解以下内容:

  1. 我应该如何改进这种方法以获得最佳查找性能?例如,如果我将唯一 id 存储为 字节数组而不是字符串?或者是否有一些特殊的编解码器或过滤器可以使用?

  2. 通过唯一 id 查找文档的时间复杂度是多少?由于索引对于每个文档至少包含一个唯一术语,因此查找时间将随着文档数量 (O(n)) 线性增加,对吗?


Theory

有一个博客文章 http://blog.mikemccandless.com/2014/05/choosing-fast-unique-identifier-uuid.html关于 Lucene 术语索引和查找性能。它清楚地揭示了通过 id 查找文档的复杂性的所有细节。这篇文章很旧了,但自那以后没有任何改变。

以下是与您的问题相关的一些要点:

  • Lucene 是一个搜索引擎,其中检索的最小元素是文本术语,因此这意味着:二进制、数字和字符串字段在BlockTree 术语词典 http://lucene.apache.org/core/4_8_0/core/org/apache/lucene/codecs/BlockTreeTermsWriter.html.
  • In general, the complexity of lookup depends on the term length: Lucene uses an in-memory prefix-trie index structure to perform a term lookup. Due to restrictions of real-world hardware and software implementations (in order to avoid superfluous disk reads and memory overflow for extremely large tries), Lucene uses a BlockTree structure. This means it stores prefix-trie in small chunks on disk and loads only one chunk at time. This is why it's so important to generate keys in an easy-to-read order. So let's arrange the factors according to the degree of their influence:
    • 术语的长度 - 要加载更多块
    • term 的模式 - 避免多余的读取
    • 术语计数 - 减少块计数

算法和复杂性

令 term 为单个字符串,令 term 字典为一大组术语。如果我们有一个术语字典,并且需要知道字典中是否有单个术语,则 trie(以及作为子类的最小确定性非循环有限状态自动机 (DAFSA))是可以帮助我们的数据结构。关于你的问题:“如果哈希查找可以做同样的事情,为什么要使用尝试?”,这里有几个原因:

  • 尝试可以在 O(L) 时间内找到字符串(其中 L 表示单个术语的长度)。与最坏情况下的哈希表相比(哈希表需要线性扫描以防哈希冲突以及像 MurmurHash3 这样的复杂哈希算法),或者类似于完美情况下的哈希表,这要快一些。
  • 哈希表只能找到与我们要查找的单个术语完全匹配的字典术语;而 trie 允许我们找到具有单个不同字符、共同前缀、缺少字符等的术语。
  • trie 可以按键提供条目的字母顺序排序,因此我们可以按字母顺序枚举所有术语。
  • trie(尤其是 DAFSA)通过重复数据删除提供了非常紧凑的术语表示。

Here is an example of DAFSA for 3 terms: bath, bat and batch: Example of DAFSA Data Structure

在进行键查找时,请注意,降低自动机(或特里树)中的单个级别是在恒定时间内完成的,并且每次算法降低自动机(特里树)中的单个级别时,都会从术语中删除一个字符,所以我们可以得出结论,在自动机(trie)中找到一个项可以在 O(L) 时间内完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Lucene文档中定义主键字段以获得最佳的查找性能? 的相关文章

  • 在 Lucene 中正确索引纬度和经度值

    我正在使用 Lucene API 开发 给定半径内基于 美国的最近城市搜索 功能 我在 Lucene 中索引城市的纬度和经度值 如下所示 doc Add new Field latitude paddedLatitude Field Sto
  • 如何为 PhraseQuery 搜索设置 Lucene 标准分析器?

    Lucene 上的各种教程给我的印象是 如果我这样做 IndexWriter writer new IndexWriter indexPath new StandardAnalyzer Version LUCENE CURRENT true
  • Hibernate 搜索中的重复过滤器

    我知道Lucene中有一个内置的DuplicateFilter 可以对Lucene的结果进行重复数据删除 对于用户在重复率非常高的文档数据库上进行搜索来说 这是一个非常重要的功能 由于我正在使用 Hibernate Search 进行全文索
  • lucene standardanalyzer 是否删除停用词并具有词干提取功能?

    我已经使用indexWriter测试了standardanalyzer 发现它会自动删除停用词 但是 我没有添加停用词列表 因为以下代码是我使用的 StandardAnalyzer analyzer new StandardAnalyzer
  • 为什么 Lucene QueryParser 需要分析器

    我是 Lucene 的新手 正在尝试将原始字符串解析为Query使用QueryParser 我想知道为什么QueryParser Parse 方法根本需要分析器参数吗 如果分析与查询有关 那么Analyzer处理常规时应指定Query对象以
  • Lucene 查询解析器在查询条件中带有“/”

    当我尝试在 Lucene 中搜索诸如 解决方法 修复 之类的内容时 它会抛出此错误 org apache lucene queryparser classic ParseException Cannot parse workaround f
  • 重用 Runnable 的最佳方式

    我有一个实现的类Runnable目前我正在使用 Executor 作为线程池来运行任务 将文档索引到 Lucene executor execute new LuceneDocIndexer doc writer 我的问题是我的 Runna
  • 为什么路由不能与 ElasticSearch Bulk API 一起使用?

    我正在向 ElasticSearch 设置批量请求并指定要路由到的分片 但是当我运行它时 文档会被发送到不同的分片 这是 ElasticSearch 批量中的错误吗 当我只索引单个文档时它就有效 当我搜索时它有效 但当我进行批量导入时则不然
  • 嵌套布尔查询?

    我正在使用 BooleanQuery 来组合多个查询 我发现如果我向 BooleanQuery 添加 BooleanQuery 则不会返回任何结果 添加的 BooleanQuery 是一个 MUST NOT 查询 例如 city id 10
  • 如何在 Lucene 6 中对数字字段进行排序

    我想根据数字字段对搜索结果进行排序 在下面的示例代码中 我想根据 年龄 字段进行排序 我从使用以下答案开始 如何在 Lucene 6 中对 IntPont 或 LongPoint 字段进行排序 https stackoverflow com
  • IntPoint 没有索引整数值

    当我们尝试使用字段类型 IntPoint 对整数值进行索引时 这些值似乎没有正确传输到我们的 Lucene 索引中 我们正在使用 Lucene 6 0 根据 Lucene 文档的代码片段 doc add new IntPoint LENGT
  • 每个领域都有不同的分析仪

    如何为使用 Lucene 索引的文档中的每个字段启用不同的分析器 例子 RAMDirectory dir new RAMDirectory IndexWriter iw new IndexWriter dir new StandardAna
  • Solr 中的多值字段排序

    我有一个 Solr 索引 将每个产品的价格存储在多值字段中 我需要按价格对结果集进行排序 其中价格从低到高 从高到低 我尝试对价格进行排序 它显示错误您无法对 multivalued True 字段进行排序 下面是我的 solr XML
  • 对 solr 搜索结果进行排序。给出错误无法对多值字段进行排序:名称

    我对 Apache Solr 搜索比较陌生 我正在尝试对 Solr 查询中的结果集进行排序 查询 名称 abc AND 隐藏 false sort name desc 它显示错误 无法对多值字段进行排序 名称 Solr版本是 7 2 1 如
  • 在具有多个 Web 服务器的现有 .NET / SQL Server 堆栈上实施 Lucene

    我想考虑使用 Lucene 为我当前管理的网站提供全文搜索解决方案 该网站完全基于 SQL Server 2008 C NET 4 技术构建 我要索引的数据实际上非常简单 每个记录只有几个字段 并且只有其中一个字段实际上是可搜索的 我不清楚
  • apache solr:group by 产生的数据总和

    我们有一个要求 需要按特定字段对记录进行分组 并获取相应数字字段的总和 前任 select userid sum click count from user action group by userid 我们尝试使用 apache solr
  • Solr 过滤查询 - 字符串与整数

    假设我正在尝试查询一堆具有类别的文档 并且我想将查询限制为指定的类别 据我所知 这只是使用 fq 参数 过滤器查询 我想知道将参数设置为整 数而不是字符串或数据通常的情况是否会提高性能 我只是会在右侧犯错 但我想我应该仔细检查一下 以防万一
  • 我们可以同时使用拼音标记和同义词吗?

    我正在尝试同时启用语音分析器和同义词 这似乎不起作用 它们一起使用有错吗 在下面的实现中 我希望使用同义词转换搜索查询 然后使用语音分析器来检索结果 但我的同义词在这里完全被忽略了 如果我在创建索引时删除语音分析器 那么同义词就可以正常工作
  • Solr:在带有空格的字符串上使用通配符

    我的问题与这里讨论的问题基本相同 带空格的 Solr 通配符查询 https stackoverflow com questions 10023133 solr wildcard query with whitespace 但这个问题没有得
  • 在elasticsearch中转义特殊字符

    我正在使用Elasticsearch python 客户端 https elasticsearch py readthedocs io en master 对我们托管的 elasticsearch 实例进行一些查询 我注意到一些字符需要转义

随机推荐

  • 多线程环境下什么是busy spin?

    什么是多线程环境下的 Busy Spin 它有什么用处以及如何在多线程环境中用java实现它 它以什么方式有助于提高应用程序的性能 其他一些答案忽略了忙碌等待的真正问题 除非您正在谈论一个您关心保存的应用程序电气功率 那么消耗 CPU 时间
  • 多重采样时如何解析 OpenGL 纹理中的深度值?

    我正在使用 FBO 将场景渲染为深度纹理 GL DEPTH COMPONENT 当我在应用程序中启用多重采样时 这些样本将解析为单个纹素 但它们是如何组合的 是存储到纹理的最近样本的深度 还是样本的平均值 此行为是否依赖于供应商 See t
  • 如何在 C# 中将字符串偏移量转换为时间跨度

    我正在尝试将转换时间转换为用户的时区 但我没有 Windows 时区字符串 例如 太平洋标准时间 我所拥有的只是一个字符串偏移量 例如 07 00 看来我需要创建一个时间跨度 是手动解析该字符串的唯一方法吗 似乎应该有一种方法使用字符串偏移
  • SQL GROUP BY:连续性间隔?

    这个想法是说你有下表 oID Area 1 5 2 2 3 3 5 3 6 4 7 5 如果可以按连续性分组 则此伪查询 SELECT SUM Area FROM sample table GROUP BY CONTINUITY oID 会
  • C# 二维int数组,对所有元素求和

    我尝试编写一个程序来对数组中的元素求和 但我有 系统索引超出范围异常 MVS 上的错误 有人能告诉我我的错误在哪里吗 public static int Sum int arr int total 0 for int i 0 i lt ar
  • 理解递归合并排序过程背后的直觉

    我对以下代码的以下输出感到困惑 def msort3 x print splitting x result if len x lt 2 print merging x return x mid int len x 2 y msort3 x
  • Visual Studio 2017 RC 安装错误“指定的帐户已存在。”

    当我尝试安装 Visual Studio 2017 RC 时 出现此错误 1764 001d 2016 11 20T10 14 21 Package Microsoft Ancm IISExpress Msi version 1 0 196
  • Numba JIT 比带有参数化函数的纯 Python 慢

    我刚刚写了一个简单的基准 https www matecdev com posts julia python numba cython html比较 Numba 和 Julia 并进行一些讨论 我想知道我的 Numba 代码是否可以以某种方
  • 如何以编程方式将项目添加到 arrayList 中的字符串数组?

    这是我的数组 xml文件在分辨率 值 folder
  • Jquery Draggable 具有多个句柄

    是否有可能有一个draggable具有多个句柄的元素 我初始化它两次 每次都使用不同的句柄参数 但它不起作用 只有第一个起作用 您应该只传递 handle 参数一次 它可以是选择器或元素 因此 要使其与多个句柄一起使用 elem dragg
  • 编写字体查看器 - 获取字体属性,动态加载 ttf

    我正在尝试使用 VB6 VB5 代码 在 Windows 下 为 TrueType OpenType 字体编写一个字体查看器 这是令人惊讶的困难 1 在VB winAPI中 我没有找到如何提取字体的名称或一般的字体属性 2 我可以安装字体
  • preg_match_all 和引号内的换行符

    另一个菜鸟正则表达式问题 问题 我可能做了一些愚蠢的事情 所以我想我应该利用 SO 常客的聪明才智 尝试匹配换行符 但前提是它们出现在双引号或单引号内 我还想捕获引号之间但不包含换行符的字符串 好的 这就是我得到的 有输出 下面是我想要得到
  • 在 Eclipse Maven 项目中找不到 persistence.xml

    我无法修复persistence xml file not foundeclipse问题 这是一个简单的测试项目 Maven Nature 用于非常基本的EJB测试 该文件确实在src main resources META INF 这是p
  • 应用程序开发人员犯的数据库开发错误[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 为什么Java 8中没有BooleanConsumer?

    恐怕这是一个有点愚蠢的问题 有没有人可以告诉我为什么没有BooleanConsumer与相反BooleanSupplier https docs oracle com javase 8 docs api java util function
  • 获取泛型参数的类型

    我编写了一个小函数来更好地处理类型 function evaluate variable any type string any switch type case string return String variable case num
  • 如何在Java中创建临时目录/文件夹?

    是否有一种标准且可靠的方法在 Java 应用程序中创建临时目录 有Java 问题数据库中的一个条目 http bugs java com bugdatabase view bug do bug id 4735419 其中的注释中有一些代码
  • 如何将 pandas 数据添加到现有 csv 文件?

    我想知道是否可以使用 pandasto csv 函数将数据框添加到现有 csv 文件 csv 文件与加载的数据具有相同的结构 您可以在 pandas 中指定 python 写入模式to csv http pandas pydata org
  • Scala 何时需要分号

    我在工作中被锁定的电脑困住了 但我正在尝试练习我的 Scala 我正在使用 Ideone com 因为我什至无法安装scalac 无论如何 这不能编译 class DPt var name String var x Double var y
  • 如何在Lucene文档中定义主键字段以获得最佳的查找性能?

    在我的 Lucene 索引 v7 2 中创建文档时 我添加了uid包含唯一 id key 字符串 的字段 doc add new StringField uid uid Field Store YES 为了稍后检索该文档 我为给定的唯一 I