2016-11-18 109 views
1

我想檢查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

散列衝突本身並不一定是壞的,只要它被正確處理。你目前如何解決衝突? –

回答

2

如果你用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