如何使用Lucene生成唯一ID?

时间:2011-02-20 18:28:53

标签: java lucene

我正在使用Lucene存储(以及索引)各种文档。

每个文档都需要一个持久的唯一标识符(用作URL的一部分)。

如果我使用的是SQL数据库,我可以使用integer primary key auto_increment(或类似)字段为每个添加的记录自动生成唯一ID。

Lucene有没有办法做到这一点?

我知道Lucene的文件已编号,但已注意到这些数字会随着时间的推移重新分配。

(我使用的是Lucene 3.0.3的Java版本。)

4 个答案:

答案 0 :(得分:4)

正如larsmans所说,你需要把它存放在一个单独的领域。我建议您将字段编入索引以及存储,并使用KeywordAnalyzer对其进行索引。 您可以在内存中保留一个计数器,并为每个新文档更新它。

剩余问题仍然存在 - 如何在Lucene进程停止时存储最大id。一种可能性是使用保存最大id的文本文件。

我相信Flexible Indexing将允许您将最大ID添加到索引作为“全局”字段。如果您愿意使用Lucene的主干,您可以尝试灵活的索引以确定它是否符合要求。

答案 1 :(得分:2)

对于类似情况,我使用以下算法(与Lucene无关,但无论如何都可以使用它。)

  • 新建AtomicLong。从System.currentTimeMillis()System.nanoTime()
  • 获得的初始值开始
  • 通过在.incrementAndGet上调用.getAndIncrementAtomicLong来生成每个下一个ID。
  • 如果系统重新启动,AtomicLong会在启动期间再次初始化为当前时间戳。

优点:简单,有效,线程安全,无阻塞。如果您需要群集ID支持,只需在现有long上添加hi/lo algorithm空间或牺牲一些高字节。

如果添加新实体的频率超过1 / ms(对于System.currentTimeMillis())或1 / ns(对于System.nanoTime()),

缺点:不起作用。不能容忍时钟异常。

可以考虑使用UUID作为另一种选择。 UUID中重复的概率为virtually non-existant

答案 2 :(得分:0)

编辑:一些评论者提出了这种方法的可能问题,我没有时间对其进行彻底测试。我将它留在这里,因为Yuval F.指的是它。请不要不必要地投票。

给定IndexWriter w,您可以使用w.maxDoc() + 1作为ID并将其(作为字符串)存储在单独的Field中。确保Fieldstored

答案 3 :(得分:0)

尝试在要编制索引的数据源中查找唯一值,并将其存储在lucene文档中。数据源可以是mysql数据库,文件系统中的文件等等。

例如,如果要索引mysql数据库中的内容,则可以使用tablename和主键ID" tablename_rowID "来汇编唯一ID。

让我们假设您要从两个表格'页面'和评论'表;对于页面表格中的每一行,您都可以使用" page_28"生成一个唯一的ID。对于页面表中ID为28的行。同样,假设您在评论表中索引第36行,您的唯一ID将是" comment_36"。

如果所有选项都失败了,那么我会坚持使用UUID。有了一些额外的偏执,这可能是一个附加到now()的时间戳的UUID。