Java 针对大型数据集存储和匹配名称的有效方法

Java 针对大型数据集存储和匹配名称的有效方法,java,architecture,full-text-search,pattern-matching,Java,Architecture,Full Text Search,Pattern Matching,对于像数据丢失预防这样的工具,我需要查找不同类型的数据,如驾照号、社会保险号、姓名等。虽然大多数数据是基于模式的,因此可以使用正则表达式的模式匹配进行查找,但姓名恰好是一个非常广泛的类别。实际上,可以有任何一组字符组成一个名称。然而,为了使它成为一个有意义的查找,我认为我应该只根据定义的名称词典查找它们。以下是我的想法 提供名称字典作为配置项。这看起来更合理,因为对于每个用例,名称可能因地理区域而异。我正在寻找用Java实现这一点的最佳实践。基本上就是这些问题- 存储名称的良好数据结构是什么。S

对于像数据丢失预防这样的工具,我需要查找不同类型的数据,如驾照号、社会保险号、姓名等。虽然大多数数据是基于模式的,因此可以使用正则表达式的模式匹配进行查找,但姓名恰好是一个非常广泛的类别。实际上,可以有任何一组字符组成一个名称。然而,为了使它成为一个有意义的查找,我认为我应该只根据定义的名称词典查找它们。以下是我的想法

提供名称字典作为配置项。这看起来更合理,因为对于每个用例,名称可能因地理区域而异。我正在寻找用Java实现这一点的最佳实践。基本上就是这些问题-

  • 存储名称的良好数据结构是什么。Set作为第一个选项出现在脑海中,是否有更好的选项,如内存数据库
  • 我应该如何在大型数据集中搜索这些名称。这些数据集非常大,我只能一行一行地读取它们
  • 还有其他选择吗

  • 请看一看和项目。

    您可以通过全文索引或在线搜索来完成。

    我更喜欢全文索引,例如使用。您必须定义索引器如何在文本中查找标记(通过定义标记模式和不关心模式)

    • 已知模式(如许可证编号)应在索引时用其类型进行注释。查询带注释类型(如许可证编号)的索引将返回所有包含的许可证编号
    • 灵活的模式(如名称)应该作为标记进行索引。然后,您可以迭代合法名称集合并使用它查询索引
    • 这种方法不是最灵活的,但它对数据文件集的更改(只需将新文件放入索引)或名称集的更改(只需在索引中查询新名称)非常健壮
    • 在这种方法中,如何存储名称集实际上与性能无关
    另一种方法是搜索多个字符串(名称)。请注意,对于多个字符串有特殊的搜索算法,并且大多数算法都有一个首选的参数范围(模式大小、字母表大小、要搜索的模式数)。你可以在这里得到一些印象

    • 这种方法允许您使用更灵活的字符串模式
    • 但是,它对名称集的修改并不健壮(然后必须重复完整的搜索)
    • Multi-string通常会接受一组字符串进行搜索,但它们会以特定于算法的方式存储这组字符串(大多数使用trie)
    编辑:

    使用基于DFA的自动机可以高效搜索多个模式/字符串。

    第一次我想在我选择的文本中高效搜索。它的自动机非常高效,但它是为匹配而优化的,而不是为搜索而优化的(搜索是以朴素的方式完成的)

    然后我转向自己的实现。它以DFA为基础,但略慢于金砖四国。搜索算法不像金砖四国那样幼稚,但增加了一些开销

    你可以找到一个比较两者的方法。基准测试可视化了基于DFA的正则表达式的问题——如果正则表达式很大,编译这样一个DFA的时间可能会非常昂贵


    我目前倾向于实现多字符串/模式搜索。它关注的是搜索性能,但我不知道它与上面的解决方案相比如何。在文本中搜索多个正则表达式模式的最常见情况将比上述解决方案更有效。

    这两个看起来很有趣,特别是CQEngine,我将进一步评估它们。谢谢。我们最初使用的是基于Lucene的方法,最近又改用了,因为我们的用例更多的是一次性搜索,所以与使用regex的直接模式匹配相比,索引在这里的成本有点高。对于指定的用例,我正在评估答案中建议的CQEngine,并发现它很有希望。它基本上是在封面下使用索引,在这里索引名称数据库是有意义的,因为这基本上是固定不变的。根据大小,我可以选择将其保存在内存或磁盘中。提示:使用
    java.util.Pattern
    搜索多个字符串效率很低(理论上是指数运行时)。转向确定性正则表达式或多字符串搜索可以节省很多性能。如果您的名称数据库已经太大了,这是一个问题,那么使用正则表达式搜索本身将是一个主要问题。google搜索确定性正则表达式会生成与DFA相关的结果,java.util.Pattern会在封面下使用NFA,我看不到任何可用的免费java库来将正则表达式转换为DFA。你有更多的指针吗?这很好。Rexlex似乎适合我的情况,我们多次匹配一个正则表达式,表达式有点复杂。我将在我的项目中尝试rexlex,看看它的性能如何。谢谢。