如何获取Lucene模糊搜索结果的匹配项?

发布于 2024-11-05 01:02:18 字数 477 浏览 0 评论 0原文

使用 Lucene 模糊搜索时如何获得匹配的模糊项及其偏移量?

    IndexSearcher mem = ....(some standard code)

    QueryParser parser = new QueryParser(Version.LUCENE_30, CONTENT_FIELD, analyzer);

    TopDocs topDocs = mem.search(parser.parse("wuzzy~"), 1);
    // the ~ triggers the fuzzy search as per "Lucene In Action" 

模糊搜索效果很好。如果文档包含术语“fuzzy”或“luzzy”,则它被匹配。如何获得匹配的术语以及它们的偏移量是多少?

我已确保所有 CONTENT_FIELD 均使用 termVectorStored 添加,其中包含 Positions 和 Offsets 。

how do you get the matching fuzzy term and its offset when using Lucene Fuzzy Search?

    IndexSearcher mem = ....(some standard code)

    QueryParser parser = new QueryParser(Version.LUCENE_30, CONTENT_FIELD, analyzer);

    TopDocs topDocs = mem.search(parser.parse("wuzzy~"), 1);
    // the ~ triggers the fuzzy search as per "Lucene In Action" 

The fuzzy search works fine. If a document contains the term "fuzzy" or "luzzy", it is matched. How do I get which term matched and what are their offsets?

I have made sure that all CONTENT_FIELDs are added with termVectorStored with positions and offsets .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情未る 2024-11-12 01:02:19

没有直接的方法可以做到这一点,但是我重新考虑了 Jared 的建议并能够使解决方案发挥作用。

我在这里记录这一点,以防其他人遇到同样的问题。

创建一个实现 org.apache.lucene.search.highlight.Formatter 的类

public class HitPositionCollector implements Formatter
{
    // MatchOffset is a simple DTO
    private List<MatchOffset> matchList;
    public HitPositionCollector(
    {
        matchList = new ArrayList<MatchOffset>();
    }

    // this ie where the term start and end offset as well as the actual term is captured
    @Override
    public String highlightTerm(String originalText, TokenGroup tokenGroup)
    {
        if (tokenGroup.getTotalScore() <= 0)
        {
        }
        else
        {
            MatchOffset mo= new MatchOffset(tokenGroup.getToken(0).toString(), tokenGroup.getStartOffset(),tokenGroup.getEndOffset());
            getMatchList().add(mo);
        }

        return originalText;
    }

    /**
    * @return the matchList
    */
    public List<MatchOffset> getMatchList()
    {
        return matchList;
    }
}

主代码

public void testHitsWithHitPositionCollector() throws Exception
{
    System.out.println(" .... testHitsWithHitPositionCollector");
    String fuzzyStr = "bro*";

    QueryParser parser = new QueryParser(Version.LUCENE_30, "f", analyzer);
    Query fzyQry = parser.parse(fuzzyStr);
    TopDocs hits = searcher.search(fzyQry, 10);

    QueryScorer scorer = new QueryScorer(fzyQry, "f");

    HitPositionCollector myFormatter= new HitPositionCollector();

    //Highlighter(Formatter formatter, Scorer fragmentScorer)
    Highlighter highlighter = new Highlighter(myFormatter,scorer);
    highlighter.setTextFragmenter(
        new SimpleSpanFragmenter(scorer)
    );

    Analyzer analyzer2 = new SimpleAnalyzer();

    int loopIndex=0;
    //for (ScoreDoc sd : hits.scoreDocs) {
        Document doc = searcher.doc( hits.scoreDocs[0].doc);
        String title = doc.get("f");

        TokenStream stream = TokenSources.getAnyTokenStream(searcher.getIndexReader(),
                                    hits.scoreDocs[0].doc,
                                    "f",
                                    doc,
                                    analyzer2);

        String fragment = highlighter.getBestFragment(stream, title);

        System.out.println(fragment);
        assertEquals("the quick brown fox jumps over the lazy dog", fragment);
        MatchOffset mo= myFormatter.getMatchList().get(loopIndex++);

        assertTrue(mo.getEndPos()==15);
        assertTrue(mo.getStartPos()==10);
        assertTrue(mo.getToken().equals("brown"));
}

There was no straight forward way of doing this, however I reconsidered Jared's suggestion and was able to get the solution working.

I am documenting this here just in case someone else has the same issue.

Create a class that implements org.apache.lucene.search.highlight.Formatter

public class HitPositionCollector implements Formatter
{
    // MatchOffset is a simple DTO
    private List<MatchOffset> matchList;
    public HitPositionCollector(
    {
        matchList = new ArrayList<MatchOffset>();
    }

    // this ie where the term start and end offset as well as the actual term is captured
    @Override
    public String highlightTerm(String originalText, TokenGroup tokenGroup)
    {
        if (tokenGroup.getTotalScore() <= 0)
        {
        }
        else
        {
            MatchOffset mo= new MatchOffset(tokenGroup.getToken(0).toString(), tokenGroup.getStartOffset(),tokenGroup.getEndOffset());
            getMatchList().add(mo);
        }

        return originalText;
    }

    /**
    * @return the matchList
    */
    public List<MatchOffset> getMatchList()
    {
        return matchList;
    }
}

Main Code

public void testHitsWithHitPositionCollector() throws Exception
{
    System.out.println(" .... testHitsWithHitPositionCollector");
    String fuzzyStr = "bro*";

    QueryParser parser = new QueryParser(Version.LUCENE_30, "f", analyzer);
    Query fzyQry = parser.parse(fuzzyStr);
    TopDocs hits = searcher.search(fzyQry, 10);

    QueryScorer scorer = new QueryScorer(fzyQry, "f");

    HitPositionCollector myFormatter= new HitPositionCollector();

    //Highlighter(Formatter formatter, Scorer fragmentScorer)
    Highlighter highlighter = new Highlighter(myFormatter,scorer);
    highlighter.setTextFragmenter(
        new SimpleSpanFragmenter(scorer)
    );

    Analyzer analyzer2 = new SimpleAnalyzer();

    int loopIndex=0;
    //for (ScoreDoc sd : hits.scoreDocs) {
        Document doc = searcher.doc( hits.scoreDocs[0].doc);
        String title = doc.get("f");

        TokenStream stream = TokenSources.getAnyTokenStream(searcher.getIndexReader(),
                                    hits.scoreDocs[0].doc,
                                    "f",
                                    doc,
                                    analyzer2);

        String fragment = highlighter.getBestFragment(stream, title);

        System.out.println(fragment);
        assertEquals("the quick brown fox jumps over the lazy dog", fragment);
        MatchOffset mo= myFormatter.getMatchList().get(loopIndex++);

        assertTrue(mo.getEndPos()==15);
        assertTrue(mo.getStartPos()==10);
        assertTrue(mo.getToken().equals("brown"));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文