繁体   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