github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/queryparser/classic/queryBuilder.go (about) 1 package classic 2 3 import ( 4 "github.com/balzaczyy/golucene/core/analysis" 5 ta "github.com/balzaczyy/golucene/core/analysis/tokenattributes" 6 "github.com/balzaczyy/golucene/core/index" 7 "github.com/balzaczyy/golucene/core/search" 8 "github.com/balzaczyy/golucene/core/util" 9 ) 10 11 type QueryBuilder struct { 12 analyzer analysis.Analyzer 13 enablePositionIncrements bool 14 } 15 16 func newQueryBuilder() *QueryBuilder { 17 return &QueryBuilder{ 18 enablePositionIncrements: true, 19 } 20 } 21 22 // L193 23 func (qp *QueryBuilder) createFieldQuery(analyzer analysis.Analyzer, 24 operator search.Occur, field, queryText string, quoted bool, phraseSlop int) search.Query { 25 26 assert(operator == search.SHOULD || operator == search.MUST) 27 assert(analyzer != nil) 28 // use the analyzer to get all the tokens, and then build a TermQuery, 29 // PraseQuery, or nothing based on the term count 30 var buffer *analysis.CachingTokenFilter 31 var termAtt ta.TermToBytesRefAttribute 32 var posIncrAtt ta.PositionIncrementAttribute 33 var numTokens int 34 var positionCount int 35 var severalTokensAtSamePosition bool 36 if err := func() (err error) { 37 var source analysis.TokenStream 38 defer func() { 39 util.CloseWhileSuppressingError(source) 40 }() 41 42 if source, err = analyzer.TokenStreamForString(field, queryText); err != nil { 43 return 44 } 45 if err = source.Reset(); err != nil { 46 return 47 } 48 buffer = analysis.NewCachingTokenFilter(source) 49 buffer.Reset() 50 51 termAtt = buffer.Attributes().Get("TermToBytesRefAttribute").(ta.TermToBytesRefAttribute) 52 posIncrAtt = buffer.Attributes().Get("PositionIncrementAttribute").(ta.PositionIncrementAttribute) 53 54 if termAtt != nil { 55 hasMoreTokens, err := buffer.IncrementToken() 56 for hasMoreTokens && err == nil { 57 numTokens++ 58 positionIncrement := 1 59 if posIncrAtt != nil { 60 positionIncrement = posIncrAtt.PositionIncrement() 61 } 62 if positionIncrement != 0 { 63 positionCount += positionIncrement 64 } else { 65 severalTokensAtSamePosition = true 66 } 67 hasMoreTokens, err = buffer.IncrementToken() 68 } // ignore error 69 } 70 return nil 71 }(); err != nil { 72 panic(err) 73 } 74 75 // rewind the buffer stream 76 buffer.Reset() 77 78 var bytes *util.BytesRef 79 if termAtt != nil { 80 bytes = termAtt.BytesRef() 81 } 82 83 if numTokens == 0 { 84 return nil 85 } else if numTokens == 1 { 86 if hasNext, err := buffer.IncrementToken(); err == nil { 87 assert(hasNext) 88 termAtt.FillBytesRef() 89 } // safe to ignore error, because we know the number of tokens 90 return qp.newTermQuery(index.NewTermFromBytes(field, util.DeepCopyOf(bytes).ToBytes())) 91 } else { 92 if severalTokensAtSamePosition || !quoted { 93 if positionCount == 1 || !quoted { 94 // no phrase query: 95 96 if positionCount == 1 { 97 panic("not implemented yet") 98 } else { 99 // multiple positions 100 q := qp.newBooleanQuery(false) 101 var currentQuery search.Query 102 for i := 0; i < numTokens; i++ { 103 hasNext, err := buffer.IncrementToken() 104 if err != nil { 105 continue // safe to ignore error, because we know the number of tokens 106 } 107 assert(hasNext) 108 termAtt.FillBytesRef() 109 110 if posIncrAtt != nil && posIncrAtt.PositionIncrement() == 0 { 111 panic("not implemented yet") 112 } else { 113 if currentQuery != nil { 114 q.Add(currentQuery, operator) 115 } 116 currentQuery = qp.newTermQuery(index.NewTermFromBytes(field, util.DeepCopyOf(bytes).ToBytes())) 117 } 118 } 119 q.Add(currentQuery, operator) 120 return q 121 } 122 } else { 123 panic("not implemented yet") 124 } 125 } else { 126 panic("not implemented yet") 127 } 128 panic("should not be here") 129 } 130 } 131 132 // L379 133 func (qp *QueryBuilder) newBooleanQuery(disableCoord bool) *search.BooleanQuery { 134 return search.NewBooleanQueryDisableCoord(disableCoord) 135 } 136 137 func (qp *QueryBuilder) newTermQuery(term *index.Term) search.Query { 138 return search.NewTermQuery(term) 139 }