600M语句的Java哈希字符串

问题描述:

我想检查600M阿拉伯语句子的精确重复项(每个小于150个字符)。所以,我使用Lucene将文本和它们的哈希索引。 我散列文本如下:600M语句的Java哈希字符串

MessageDigest digester = MessageDigest.getInstance("SHA-256"); 
digester.update(sentence.getBytes()); 
int hashValue = new String(digester.digest()).hashCode(); 

我的指数具有以下字段:

text: <sentence> 
hash: <hashValue> 

我的想法是,我有句名单,我希望得到他们确切的重复,所以我可以使用它们的哈希来搜索lucene。

ScoreDoc[] results; 
TopScoreDocCollector collector = TopScoreDocCollector.create(1000); 
Query rangeQuery = LegacyNumericRangeQuery.newIntRange("hash", hashValue, hashValue, true, true); 
searcher.search(rangeQuery, collector); 
results = collector.topDocs().scoreDocs; 

问题是,当我这样做的时候,我得到了不同的相同散列的句子!所以,我没有达到我想要的!

所以我希望得到答案了以下问题:

  • 我会得到更少的碰撞,如果我用这个散列函数哈希的话,而不是句子?
  • 是否有更好的散列函数与更少的集合?
  • 有没有更好的方式来完成我的任务?
  • 即使散列函数使用字节,哈希语言是否依赖,对于utf-8文本,它们是否更好?

我很感谢您的回应! Regards, Reem

+3

*“我得到不同的句子与相同的散列”*好吧,是啊!哈希不保证是唯一的。他们*不能*是唯一的。 – Andreas

+0

散列是一个整数,所以它的值是有限的 –

+0

散列冲突本身并不一定是坏的,只要它被正确处理。你目前如何解决冲突? –

如果你用Lucene索引它们,你并不需要哈希值。只需将句子存储为(未经确认的)StringField并使用具有准确句子的TermQuery

+0

我在存储哈希,因为我在比较它们之前正在对字符串进行一些处理(例如,删除URL),因为我想比较没有URL的文本,但最终我需要原始文本用于其他目的。 – sareem

+0

然后我会索引并搜索处理后的文本(而不是哈希)。您可以将原始语句存储在“StoredField”中。无需索引。 – RobAu

+2

查看https://lucene.apache.org/core/6_3_0/core/org/apache/lucene/document/StoredField.html – RobAu