簡體   English   中英

在Lucene文檔中添加字段

[英]Add field in Lucene document

你好我有一個32mb的文件。 它是一個簡單的字典文件,編碼1250,其中有280萬行。 每行只有一個唯一的單詞:

cat
dog
god
...

我想用Lucene搜索特定單詞字典中的每個字謎。 例如:

我想搜索單詞dog的每個字謎,lucene應該搜索我的字典並返回 在我的webapp中,我有一個Word實體:

public class Word {
    private Long id;
    private String word;
    private String baseLetters;
    private String definition;
}

和baseLetters是一個變量,它按字母順序排序,用於搜索這樣的字謎[上帝和狗的單詞將具有相同的baseLetters:dgo]。 我成功地在我的數據庫中使用這個baseLetters變量在不同的服務中搜索這樣的字謎但我有問題來創建我的字典文件的索引。 我知道我必須添加到字段:

單詞和baseLetters但我不知道該怎么做:(有人能告訴我一些方向來實現這個目標嗎?

現在我只有這樣的東西:

public class DictionaryIndexer {

private static final Logger logger = LoggerFactory.getLogger(DictionaryIndexer.class);

@Value("${dictionary.path}")
private String dictionaryPath;

@Value("${lucene.search.indexDir}")
private String indexPath;

public void createIndex() throws CorruptIndexException, LockObtainFailedException {
    try {
        IndexWriter indexWriter = getLuceneIndexer();
        createDocument();           
    } catch (IOException e) {
        logger.error(e.getMessage(), e);
    }       
 }

private IndexWriter getLuceneIndexer() throws CorruptIndexException, LockObtainFailedException, IOException {
    StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
    IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_36, analyzer);
    indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
    Directory directory = new SimpleFSDirectory(new File(indexPath));
    return new IndexWriter(directory, indexWriterConfig);
}

private void createDocument() throws FileNotFoundException {
    File sjp = new File(dictionaryPath);
    Reader reader = new FileReader(sjp);

    Document dictionary = new Document();
    dictionary.add(new Field("word", reader));
}

}

PS:還有一個問題。 如果我在Spring中將DocumentIndexer注冊為bean,那么每次重新部署我的webapp時索引都會創建/追加嗎? 和未來的DictionarySearcher一樣嗎?

Lucene不是最好的工具,因為你沒有進行搜索:你正在進行查找。 所有實際工作都發生在“索引器”中,然后您只需存儲所有工作的結果。 在任何散列類型存儲機制中查找可以是O(1)。

這是您的索引器應該做的事情:

  1. 將整個字典讀入一個簡單的結構,如SortedSetString[]
  2. 為存儲結果創建一個空的HashMap<String,List<String>> (性能可能相同)
  3. 按字母順序迭代字典(實際上任何訂單都可以工作,只需確保你點擊所有條目)
    1. 對單詞中的字母進行排序
    2. 查找存儲集合中的已排序字母
    3. 如果查找成功,請將當前單詞添加到列表中; 否則,創建一個包含該單詞的新列表並將其放入存儲Map
  4. 如果以后需要此映射,請將映射存儲在磁盤上; 否則,請將其保存在內存中
  5. 丟棄字典

以下是您的查找過程應該執行的操作:

  1. 對示例字中的字母進行排序
  2. 查找存儲集合中的已排序字母
  3. 打印從查找返回的List (或null),注意從輸出中省略樣本字

如果要節省堆空間,請考慮使用DAWG 你會發現你可以用幾百千字節而不是32MiB代表整個英語單詞詞典。 我將把它作為讀者的練習。

祝你的家庭作業好運。

函數createDocument()應該是

private void createDocument() throws FileNotFoundException {
    File sjp = new File(dictionaryPath);
    BufferedReader reader = new BufferedReader(new FileReader(sjp));

    String readLine = null;
    while((readLine = reader.readLine() != null)) {
        readLine = readLine.trim();
        Document dictionary = new Document();
        dictionary.add(new Field("word", readLine));
        // toAnagram methods sorts the letters in the word. Also makes it
        // case insensitive.
        dictionary.add(new Field("anagram", toAnagram(readLine)));
        indexWriter.addDocument(dictionary);
    }
}

如果您正在使用Lucene提供大量功能,請考慮使用基於Lucene構建的搜索平台Apache Solr

您還可以使用每個anagram組中的一個條目為索引建模。

{"anagram" : "scare", "words":["cares", "acres"]}
{"anagram" : "shoes", "words":["hoses"]}
{"anagram" : "spore", "words":["pores", "prose", "ropes"]}

這將需要在處理字典文件時更新索引中的現有文檔。 在這種情況下,Solr將幫助提供更高級別的API。 例如, IndexWriter不支持更新文檔 Solr支持更新。

這樣的索引將為每個字謎搜索提供一個結果文檔。

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM