-4

我需要在大量文件(即 600 个文件,每个 0.5 MB)中搜索特定字符串。

我正在使用 Java,所以我希望答案是 Java 库,或者在最坏的情况下,我可以从 Java 调用不同语言的库。

我需要搜索以返回文件中找到的字符串的确切位置(因此,例如 Lucene 似乎是不可能的)。

我需要尽可能快的搜索。

编辑开始:

这些文件可能具有不同的格式(即 EDI、XML、CSV),并且有时包含相当随机的数据(即数字 ID 等)。这就是为什么我初步排除了基于索引的搜索引擎。

将多次搜索文件以查找相似但不同的字符串(即,可能具有相似长度和格式的 ID,但它们通常不同)。

编辑结束

有任何想法吗?

4

2 回答 2

1

600 个 0.5 MB 的文件大约是 300MB - 现在几乎不能认为是的,更不用说大了。在任何现代计算机上进行简单的字符串搜索实际上应该比 CPU 更受 I/O 限制 - 我系统上的单个线程可以在 1.5 秒内搜索 300MB 的相对简单的正则表达式 - 如果文件下降到 0.2已经存在于操作系统缓存中。

考虑到这一点,如果您的目的是不经常执行此类搜索,那么使用某种索引可能会导致过度设计的解决方案。首先遍历所有文件,逐块或逐行读取每个文件并搜索 - 这很简单,几乎不值得拥有自己的库。

设定您的性能要求,分析您的代码,验证实际的字符串搜索是否是瓶颈,然后决定是否需要更复杂的解决方案。如果您确实需要更快的东西,您应该首先考虑以下解决方案,按复杂程度排列:

  • 使用现有的索引引擎,例如 Lucene,为每个查询过滤掉大部分文件,然后在(希望很少的)剩余文件中显式搜索您的字符串。

  • 如果您的文件不是真正的文本,那么基于单词的索引将起作用,请预处理文件以提取每个文件的术语列表并使用数据库创建自己的索引系统 - 我怀疑您会找到使用任何东西的 FTS 引擎除了用于索引的单词。

  • 如果您真的想将搜索时间减少到最少,请从您的文件中提取术语/位置对,然后将它们输入到您的数据库中。您可能仍然需要通过查看实际文件来进行验证,但这会明显更快。

PS:你根本没有提到我们讨论什么琴弦之王。它是否包含分隔的术语,例如单词,或者您的文件是否包含随机字符?搜索字符串可以以有意义的方式分解成子字符串,还是一堆字母?您的搜索字符串是固定的,还是也可以是正则表达式?这些问题中的每一个的答案都可能会显着限制什么是实际可行的,什么是不可行的——例如,索引随机字符串可能根本不可能。

编辑

从问题更新来看,术语/令牌的概念似乎普遍适用的,而不是例如在二进制文件中搜索完全随机的序列。这意味着您可以索引这些术语。通过在索引中搜索搜索字符串中存在的任何标记,您可以显着减少需要查看实际文件的情况。

  1. 你可以保留一个term->file索引。如果大多数术语对于每个文件都是唯一的,则此方法可能会提供良好的复杂性/性能折衷。本质上,您会将搜索范围缩小到一两个文件,然后仅对这些文件执行完整搜索。

  2. 你可以保留一个term->file:position索引。例如,如果您的搜索字符串是“Alan Turing”。您将首先在索引中搜索标记“Alan”和“Turing”。您将获得两个可以交叉引用的文件和位置列表。例如,通过要求标记“Alan”的位置在标记“Turing”的位置之前最多(例如,30 个字符),您将在文件中获得可以明确验证的候选位置列表。

我不确定现有的索引库会在多大程度上有所帮助。大多数都针对文本索引,并且可能会错误处理其他类型的标记,例如数字或日期。另一方面,您的情况也没有根本不同,因此您可以使用它们 - 如有必要,通过预处理您提供给它们的文件以使它们更可口。建立自己的索引系统,根据您的需要量身定制,似乎也不是太难

您还没有提到您的搜索字符串是否有任何灵活性。您希望能够搜索正则表达式吗?是否应该逐字查找搜索字符串,还是只需要查找其中的术语?空格重要吗?条款的顺序重要吗?

更重要的是,您没有提到您的文件中是否有任何类型的结构需要在搜索时加以考虑。例如,您是否希望能够将搜索限制为 XML 文件的特定元素?

于 2012-02-08T18:16:14.953 回答
1

除非您有 SSD,否则您的主要瓶颈将是所有文件访问。无论您在 Java 中使用什么,它都需要大约 10 秒来读取文件。

如果你有 SSD,读取文件不会有问题,Java 中的 CPU 速度会更重要。

如果您可以为文件创建索引,这将有很大帮助。

于 2012-02-08T18:16:15.750 回答