1// Copyright (c) 2017 Couchbase, Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package query 16 17import ( 18 "fmt" 19 20 "github.com/blevesearch/bleve/index" 21 "github.com/blevesearch/bleve/mapping" 22 "github.com/blevesearch/bleve/search" 23 "github.com/blevesearch/bleve/search/searcher" 24) 25 26type TermRangeQuery struct { 27 Min string `json:"min,omitempty"` 28 Max string `json:"max,omitempty"` 29 InclusiveMin *bool `json:"inclusive_min,omitempty"` 30 InclusiveMax *bool `json:"inclusive_max,omitempty"` 31 FieldVal string `json:"field,omitempty"` 32 BoostVal *Boost `json:"boost,omitempty"` 33} 34 35// NewTermRangeQuery creates a new Query for ranges 36// of text term values. 37// Either, but not both endpoints can be nil. 38// The minimum value is inclusive. 39// The maximum value is exclusive. 40func NewTermRangeQuery(min, max string) *TermRangeQuery { 41 return NewTermRangeInclusiveQuery(min, max, nil, nil) 42} 43 44// NewTermRangeInclusiveQuery creates a new Query for ranges 45// of numeric values. 46// Either, but not both endpoints can be nil. 47// Control endpoint inclusion with inclusiveMin, inclusiveMax. 48func NewTermRangeInclusiveQuery(min, max string, minInclusive, maxInclusive *bool) *TermRangeQuery { 49 return &TermRangeQuery{ 50 Min: min, 51 Max: max, 52 InclusiveMin: minInclusive, 53 InclusiveMax: maxInclusive, 54 } 55} 56 57func (q *TermRangeQuery) SetBoost(b float64) { 58 boost := Boost(b) 59 q.BoostVal = &boost 60} 61 62func (q *TermRangeQuery) Boost() float64 { 63 return q.BoostVal.Value() 64} 65 66func (q *TermRangeQuery) SetField(f string) { 67 q.FieldVal = f 68} 69 70func (q *TermRangeQuery) Field() string { 71 return q.FieldVal 72} 73 74func (q *TermRangeQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { 75 field := q.FieldVal 76 if q.FieldVal == "" { 77 field = m.DefaultSearchField() 78 } 79 var minTerm []byte 80 if q.Min != "" { 81 minTerm = []byte(q.Min) 82 } 83 var maxTerm []byte 84 if q.Max != "" { 85 maxTerm = []byte(q.Max) 86 } 87 return searcher.NewTermRangeSearcher(i, minTerm, maxTerm, q.InclusiveMin, q.InclusiveMax, field, q.BoostVal.Value(), options) 88} 89 90func (q *TermRangeQuery) Validate() error { 91 if q.Min == "" && q.Min == q.Max { 92 return fmt.Errorf("term range query must specify min or max") 93 } 94 return nil 95} 96