我有一个应用程序需要我索引几千兆字节的句子(大约 1600 万行)。
目前我的搜索按以下方式进行。
我的搜索词通常围绕一个词组展开。例如“在公园运行”。我希望能够搜索与此类似的句子或包含这些短语的一部分。我通过构造较小的短语来做到这一点:
“奔跑在” “在公园里”等
他们每个人都有一个权重(越长的权重越大)
目前,我将每一行视为一个文档。一次典型的搜索大约需要几秒钟,我想知道是否有办法提高搜索速度。
除此之外,我还需要获取匹配的内容。
例如:“我今天早上在公园里慢跑”匹配“在公园里”,我想知道它是如何匹配的。我知道用于 lucene 搜索的 Explainer,但是否有更简单的方法或是否有我可以获得的资源来学习如何从 Lucene 的 Explainer 中提取我想要的信息。
我目前正在使用正则表达式来获取匹配项。它速度很快但不准确,因为 lucene 有时会忽略标点符号和其他内容,我无法处理所有特殊情况。
最佳答案
Highlighter 比 Explainer 好,它更快。 您可以在突出显示标签后提取标签之间的匹配短语。 Java regex to extract text between tags
public class HighlightDemo {
Directory directory;
Analyzer analyzer;
String[] contents = {"running in the park",
"I was jogging in the park this morning",
"running on the road",
"The famous New York Marathon has its final miles in Central park every year and it's easy to understand why: the park, with a variety of terrain and excellent scenery, is the ultimate runner's dream. With its many paths that range in level of difficulty, Central Park allows a runner to experience clarity and freedom in this picturesque urban oasis."};
@Before
public void setUp() throws IOException {
directory = new RAMDirectory();
analyzer = new WhitespaceAnalyzer();
// indexed documents
IndexWriter writer = new IndexWriter(directory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED);
for (int i = 0; i < contents.length; i++) {
Document doc = new Document();
doc.add(new Field("content", contents[i], Field.Store.NO, Field.Index.ANALYZED)); // store & index
doc.add(new NumericField("id", Field.Store.YES, true).setIntValue(i)); // store & index
writer.addDocument(doc);
}
writer.close();
}
@Test
public void test() throws IOException, ParseException, InvalidTokenOffsetsException {
IndexSearcher s = new IndexSearcher(directory);
QueryParser parser = new QueryParser(Version.LUCENE_36, "content", analyzer);
org.apache.lucene.search.Query query = parser.parse("park");
TopDocs hits = s.search(query, 10);
SimpleHTMLFormatter htmlFormatter = new SimpleHTMLFormatter();
Highlighter highlighter = new Highlighter(htmlFormatter, new QueryScorer(query));
for (int i = 0; i < hits.scoreDocs.length; i++) {
int id = hits.scoreDocs[i].doc;
Document doc = s.doc(id);
String text = contents[Integer.parseInt(s.doc(id).get("id"))];
TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(text));
org.apache.lucene.search.highlight.TextFragment[] frag = highlighter.getBestTextFragments(tokenStream, text, false, 10);
for (int j = 0; j < frag.length; j++) {
if ((frag[j] != null) && (frag[j].getScore() > 0)) {
assertTrue(frag[j].toString().contains("<B>"));
assertTrue(frag[j].toString().contains("</B>"));
System.out.println(frag[j].toString());
}
}
}
}
}
关于java - 在 Lucene 中搜索句子并获得匹配的术语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10875604/