首页 > 解决方案 > Lucene.Net 理解为什么带有 BooleanQuery 的 TermRangeQuery 没有返回值

问题描述

我试图将过滤器应用于搜索结果,我可以成功应用“完全匹配”过滤,但我试图理解为什么我尝试对字符串字段使用 TermRangeQuery,但没有得到任何结果。例如,给定这个索引(我在下面的示例中使用 BooleanQuery,因为最终我想应用一组过滤器)

    Dim stdAnalyzer As New StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)
    Dim iWriter As New IndexWriter(directory, stdAnalyzer, IndexWriter.MaxFieldLength.UNLIMITED)
    Dim doc As New Document

    doc.Add(New Field("Name", "Apple", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Apple", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering
    iWriter.AddDocument(doc)

    doc = New Document
    doc.Add(New Field("Name", "Apple Green", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Apple Green", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering
    iWriter.AddDocument(doc)

    doc = New Document
    doc.Add(New Field("Name", "Banana", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Banana", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering
    iWriter.AddDocument(doc)

    doc = New Document
    doc.Add(New Field("Name", "Banana Yellow", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Banana Yellow", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering
    iWriter.AddDocument(doc)

    doc = New Document
    doc.Add(New Field("Name", "Orange Orange", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Orange Orange", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering
    iWriter.AddDocument(doc)

    doc = New Document
    doc.Add(New Field("Name", "Orange", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Orange", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering
    iWriter.AddDocument(doc)

    doc = New Document
    doc.Add(New Field("Name", "Pear Green", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Pear Green", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering
    iWriter.AddDocument(doc)

    doc = New Document
    doc.Add(New Field("Name", "Pear", Field.Store.YES, Field.Index.ANALYZED))        ''analyzed fields
    doc.Add(New Field("Filter_Name", "Pear", Field.Store.NO, Field.Index.NOT_ANALYZED))        ''non analyzed fields for exact matches/filtering


    iWriter.AddDocument(doc)
    iWriter.Commit()
    iWriter.Dispose()
End Sub

我可以查询Apple的完全匹配

    Using reader As IndexReader = IndexReader.Open(directory, True)
        Using Searcher As New IndexSearcher(reader)
            Using analyzer As New StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)
                Dim query As New MatchAllDocsQuery ''all docs

                Dim boolFilter As New BooleanQuery
                boolFilter.Add(New TermQuery(New Term("Filter_Name", "Apple")), Occur.MUST) ''Exact match for Apple

                Dim filter As New QueryWrapperFilter(boolFilter)
                Dim collector = TopScoreDocCollector.Create(reader.MaxDoc, False)
                Searcher.Search(query, filter, collector)
            End Using
        End Using
    End Using

但是我想执行更多和更少的查询,我尝试使用 TermRangeQuery 在名称字段(已分析)中查找比 Apple 和 Orange之间的结果,但返回 0 个结果。

                 Using reader As IndexReader = IndexReader.Open(directory, True)
        Using Searcher As New IndexSearcher(reader)
            Using analyzer As New StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)
                Dim query As New MatchAllDocsQuery ''all docs

                Dim boolFilter As New BooleanQuery
                boolFilter.Add(New TermRangeQuery("Name", "Apple", "Orange", True, True), Occur.MUST)

                Dim Filter As New QueryWrapperFilter(boolFilter)
                Dim collector = TopScoreDocCollector.Create(reader.MaxDoc, False)
                Searcher.Search(query, filter, collector)

                Debug.WriteLine("Total hits Name TermRangeQuery (Apple TO Orange): " + collector.TotalHits.ToString)

                Dim topDocs = collector.TopDocs
                For Each scoreDoc In TopDocs.ScoreDocs
                    Dim doc As Document = Searcher.Doc(scoreDoc.Doc)
                    Debug.WriteLine("Name: " + doc.GetField("Name").StringValue + " Doc ID: " + scoreDoc.Doc.ToString)
                Next

            End Using
        End Using
    End Using

但是,对字段Filter_Name(未分析)执行相同的查询确实会返回结果。

Using reader As IndexReader = IndexReader.Open(directory, True)
        Using Searcher As New IndexSearcher(reader)
            Using analyzer As New StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)
                Dim query As New MatchAllDocsQuery ''all docs

                Dim boolFilter As New BooleanQuery
                boolFilter.Add(New TermRangeQuery("Filter_Name", "Apple", "Orange", True, True), Occur.MUST)

                Dim Filter As New QueryWrapperFilter(boolFilter)
                Dim collector = TopScoreDocCollector.Create(reader.MaxDoc, False)
                Searcher.Search(query, filter, collector)

                Debug.WriteLine("Total hits Name TermRangeQuery (Apple TO Orange): " + collector.TotalHits.ToString)

                Dim topDocs = collector.TopDocs
                For Each scoreDoc In TopDocs.ScoreDocs
                    Dim doc As Document = Searcher.Doc(scoreDoc.Doc)
                    Debug.WriteLine("Name: " + doc.GetField("Name").StringValue + " Doc ID: " + scoreDoc.Doc.ToString)
                Next

            End Using
        End Using
    End Using

我在其他 lucene 示例中看到,我应该能够使用通配符(例如 [Orange TO *] .

m.谢谢

标签: lucenelucene.net

解决方案


推荐阅读