您好,我有一个 32mb 的文件。它是一个简单的字典文件,编码为 1250,其中有 280 万行。每一行只有一个唯一的词:
cat
dog
god
...
我想使用 Lucene 来搜索特定单词词典中的每个字谜。例如:
我想搜索单词 dog 的每个变位词,lucene 应该搜索我的字典并返回 dog 和 god。在我的网络应用程序中,我有一个词实体:
public class Word {
private Long id;
private String word;
private String baseLetters;
private String definition;
}
和 baseLetters 是变量,它按字母顺序排列字母以搜索此类字谜 [上帝和狗词将具有相同的 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 也会如此吗?
最佳答案
Lucene 不是执行此操作的最佳工具,因为您不是在进行搜索:您是在进行查找。所有实际工作都发生在“索引器”中,然后您只需存储所有工作的结果。在任何哈希类型的存储机制中,查找都可以是 O(1)。
这是你的索引器应该做的:
- 将整个词典读入一个简单的结构,如
SortedSet
或String[]
- 创建一个空的
HashMap<String,List<String>>
(可能大小相同,为了性能)用于存储结果 - 按字母顺序遍历字典(实际上任何顺序都可以,只要确保你命中所有条目)
- 将单词中的字母排序
- 在您的存储集合中查找已排序的字母
- 如果查找成功,将当前单词添加到列表中;否则,创建一个包含单词的新列表并将其放入存储
Map
- 如果您以后需要这张 map ,请将这张 map 存储在磁盘上;否则,将其保存在内存中
- 丢弃字典
这是您的查找过程应该执行的操作:
- 对示例单词中的字母进行排序
- 在您的存储集合中查找已排序的字母
- 打印
List
从查找返回的(或 null),注意从输出中省略示例词
如果您想节省堆空间,请考虑使用 DAWG .您会发现您可以用几百 KB 而不是 32MiB 来表示整个英语单词词典。我将把它留给读者作为练习。
祝你的家庭作业顺利。
关于java - 在 Lucene 文档中添加字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13998124/