java - 在 Lucene 中搜索句子并获得匹配的术语

标签 java search indexing lucene large-data

我有一个应用程序需要我索引几千兆字节的句子(大约 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/

相关文章:

java - 使用java下载大文件

php - 如果我想用xpath检查表行

android - 在整个 SQLite 数据库中搜索关键字以在 Android 应用程序中实现搜索功能

python - 在 numpy 中向量化这个 for 循环

matlab - 如何使用 max 或 min 返回的多维索引?

java - 使用 Spring Boot 和 Liquibase 时如何在每次集成测试后清理数据库表?

Java docker 文件。构建并测试还是只运行 jar 文件?

css - 自定义搜索栏

curl - 不使用 curl 将数据索引到 ElasticSearch

java进程停止整个进程树