你好,我有一个 32mb 的文件。这是一个简单的字典文件,编码为 1250,其中有 280 万行。每一行只有一个独特的词:

cat
dog
god
...

我想使用 Lucene 在特定单词的字典中搜索每个字谜。例如:

我想搜索单词 dog 的每个字谜,lucene 应该搜索我的字典并返回 dog god 。在我的 webapp 中,我有一个 Word 实体:
public class Word {
    private Long id;
    private String word;
    private String baseLetters;
    private String definition;
}

和 baseLetters 是按字母顺序排序的变量,用于搜索此类字谜 [god 和 dog 单词将具有相同的 baseLetters: dgo]。我在不同的服务中使用这个 baseLetters 变量成功地从我的数据库中搜索了这样的字谜,但是我在创建字典文件的索引时遇到了问题。我知道我必须添加到字段:

word 和 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 时,索引都会创建/附加吗? future 的 DictionarySearcher 也会如此吗?

最佳答案

函数 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 用于许多功能,请考虑使用 Apache Solr ,这是一个构建在 Lucene 之上的搜索平台。

您还可以为每个字谜组仅使用一个条目对索引进行建模。
{"anagram" : "scare", "words":["cares", "acres"]}
{"anagram" : "shoes", "words":["hoses"]}
{"anagram" : "spore", "words":["pores", "prose", "ropes"]}

这将需要在处理字典文件时更新索引中的现有文档。在这种情况下,Solr 将有助于使用更高级别的 API。例如, IndexWriter does not support updating documents 。 Solr 支持更新。

这样的索引将为每个字谜搜索提供一个结果文档。

希望能帮助到你。

10-07 19:33
查看更多