我正在使用Lucene存储(以及索引)各种文档。
每个文档都需要一个持久的唯一标识符(用作URL的一部分)。
如果我使用的是SQL数据库,我可以使用integer primary key auto_increment
(或类似)字段为每个添加的记录自动生成唯一ID。
Lucene有没有办法做到这一点?
我知道Lucene的文件已编号,但已注意到这些数字会随着时间的推移重新分配。
(我使用的是Lucene 3.0.3的Java版本。)
答案 0 :(得分:4)
正如larsmans所说,你需要把它存放在一个单独的领域。我建议您将字段编入索引以及存储,并使用KeywordAnalyzer对其进行索引。 您可以在内存中保留一个计数器,并为每个新文档更新它。
剩余问题仍然存在 - 如何在Lucene进程停止时存储最大id。一种可能性是使用保存最大id的文本文件。
我相信Flexible Indexing将允许您将最大ID添加到索引作为“全局”字段。如果您愿意使用Lucene的主干,您可以尝试灵活的索引以确定它是否符合要求。
答案 1 :(得分:2)
对于类似情况,我使用以下算法(与Lucene无关,但无论如何都可以使用它。)
AtomicLong
。从System.currentTimeMillis()
或System.nanoTime()
.incrementAndGet
上调用.getAndIncrement
或AtomicLong
来生成每个下一个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
中。确保Field
为stored。
答案 3 :(得分:0)
尝试在要编制索引的数据源中查找唯一值,并将其存储在lucene文档中。数据源可以是mysql数据库,文件系统中的文件等等。
例如,如果要索引mysql数据库中的内容,则可以使用tablename和主键ID" tablename_rowID "来汇编唯一ID。
让我们假设您要从两个表格'页面'和评论'表;对于页面表格中的每一行,您都可以使用" page_28"生成一个唯一的ID。对于页面表中ID为28的行。同样,假设您在评论表中索引第36行,您的唯一ID将是" comment_36"。
如果所有选项都失败了,那么我会坚持使用UUID。有了一些额外的偏执,这可能是一个附加到now()的时间戳的UUID。