0
0

added control over inclusive/exclusive numeric/date ranges

This commit is contained in:
Marty Schoch 2014-08-25 17:47:27 -04:00
parent ef59abe4c9
commit 78db88897c
6 changed files with 75 additions and 13 deletions

View File

@ -1,5 +1,9 @@
function SearchCtrl($scope, $http, $routeParams, $log, $sce) { function SearchCtrl($scope, $http, $routeParams, $log, $sce) {
$scope.inclusiveMin = true;
$scope.inclusiveMax = false;
$scope.inclusiveStart = true;
$scope.inclusiveEnd = false;
$scope.fieldNames = []; $scope.fieldNames = [];
$scope.minShouldOptions = []; $scope.minShouldOptions = [];
@ -79,6 +83,8 @@ function SearchCtrl($scope, $http, $routeParams, $log, $sce) {
"query": { "query": {
"min": parseFloat($scope.min), "min": parseFloat($scope.min),
"max": parseFloat($scope.max), "max": parseFloat($scope.max),
"inclusive_min": $scope.inclusiveMin,
"inclusive_max": $scope.inclusiveMax,
"field": $scope.field, "field": $scope.field,
} }
}). }).
@ -98,6 +104,8 @@ function SearchCtrl($scope, $http, $routeParams, $log, $sce) {
"query": { "query": {
"start": $scope.startDate, "start": $scope.startDate,
"end": $scope.endDate, "end": $scope.endDate,
"inclusive_start": $scope.inclusiveStart,
"inclusive_end": $scope.inclusiveEnd,
"field": $scope.field, "field": $scope.field,
} }
}). }).

View File

@ -15,12 +15,24 @@
<input ng-model="startDate" type="text" class="form-control" id="inputStart" placeholder=""> <input ng-model="startDate" type="text" class="form-control" id="inputStart" placeholder="">
</div> </div>
</div> </div>
<div class="form-group">
<label for="inputInclusiveStart" class="col-sm-2 control-label">Inclusive Start</label>
<div class="col-sm-10">
<input ng-model="inclusiveStart" type="checkbox" class="form-control" id="inputInclusiveStart">
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="inputEnd" class="col-sm-2 control-label">End Date</label> <label for="inputEnd" class="col-sm-2 control-label">End Date</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input ng-model="endDate" type="text" class="form-control" id="inputEnd" placeholder=""> <input ng-model="endDate" type="text" class="form-control" id="inputEnd" placeholder="">
</div> </div>
</div> </div>
<div class="form-group">
<label for="inputInclusiveEnd" class="col-sm-2 control-label">Inclusive End</label>
<div class="col-sm-10">
<input ng-model="inclusiveEnd" type="checkbox" class="form-control" id="inputInclusiveEnd">
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" ng-click="searchDateRange()">Search</button> <button type="submit" class="btn btn-primary" ng-click="searchDateRange()">Search</button>

View File

@ -15,12 +15,24 @@
<input ng-model="min" type="text" class="form-control" id="inputMin" placeholder=""> <input ng-model="min" type="text" class="form-control" id="inputMin" placeholder="">
</div> </div>
</div> </div>
<div class="form-group">
<label for="inputInclusiveMin" class="col-sm-2 control-label">Inclusive Min</label>
<div class="col-sm-10">
<input ng-model="inclusiveMin" type="checkbox" class="form-control" id="inputInclusiveMin">
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="inputMax" class="col-sm-2 control-label">Max</label> <label for="inputMax" class="col-sm-2 control-label">Max</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input ng-model="max" type="text" class="form-control" id="inputMax" placeholder=""> <input ng-model="max" type="text" class="form-control" id="inputMax" placeholder="">
</div> </div>
</div> </div>
<div class="form-group">
<label for="inputInclusiveMax" class="col-sm-2 control-label">Inclusive Max</label>
<div class="col-sm-10">
<input ng-model="inclusiveMax" type="checkbox" class="form-control" id="inputInclusiveMax">
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary" ng-click="searchNumericRange()">Search</button> <button type="submit" class="btn btn-primary" ng-click="searchNumericRange()">Search</button>

View File

@ -19,16 +19,24 @@ import (
type DateRangeQuery struct { type DateRangeQuery struct {
Start *string `json:"start,omitempty"` Start *string `json:"start,omitempty"`
End *string `json:"end,omitempty"` End *string `json:"end,omitempty"`
InclusiveStart *bool `json:"inclusive_start,omitempty"`
InclusiveEnd *bool `json:"inclusive_end,omitempty"`
FieldVal string `json:"field,omitempty"` FieldVal string `json:"field,omitempty"`
BoostVal float64 `json:"boost,omitempty"` BoostVal float64 `json:"boost,omitempty"`
DateTimeParser *string `json:"datetime_parser,omitempty"` DateTimeParser *string `json:"datetime_parser,omitempty"`
} }
func NewDateRangeQuery(start, end *string) *DateRangeQuery { func NewDateRangeQuery(start, end *string) *DateRangeQuery {
return NewDateRangeInclusiveQuery(start, end, nil, nil)
}
func NewDateRangeInclusiveQuery(start, end *string, startInclusive, endInclusive *bool) *DateRangeQuery {
return &DateRangeQuery{ return &DateRangeQuery{
Start: start, Start: start,
End: end, End: end,
BoostVal: 1.0, InclusiveStart: startInclusive,
InclusiveEnd: endInclusive,
BoostVal: 1.0,
} }
} }
@ -86,7 +94,7 @@ func (q *DateRangeQuery) Searcher(i *indexImpl, explain bool) (search.Searcher,
max = numeric_util.Int64ToFloat64(endTime.UnixNano()) max = numeric_util.Int64ToFloat64(endTime.UnixNano())
} }
return search.NewNumericRangeSearcher(i.i, &min, &max, field, q.BoostVal, explain) return search.NewNumericRangeSearcher(i.i, &min, &max, q.InclusiveStart, q.InclusiveEnd, field, q.BoostVal, explain)
} }
func (q *DateRangeQuery) Validate() error { func (q *DateRangeQuery) Validate() error {

View File

@ -13,17 +13,25 @@ import (
) )
type NumericRangeQuery struct { type NumericRangeQuery struct {
Min *float64 `json:"min,omitempty"` Min *float64 `json:"min,omitempty"`
Max *float64 `json:"max,omitempty"` Max *float64 `json:"max,omitempty"`
FieldVal string `json:"field,omitempty"` InclusiveMin *bool `json:"inclusive_min,omitempty"`
BoostVal float64 `json:"boost,omitempty"` InclusiveMax *bool `json:"inclusive_max,omitempty"`
FieldVal string `json:"field,omitempty"`
BoostVal float64 `json:"boost,omitempty"`
} }
func NewNumericRangeQuery(min, max *float64) *NumericRangeQuery { func NewNumericRangeQuery(min, max *float64) *NumericRangeQuery {
return NewNumericRangeInclusiveQuery(min, max, nil, nil)
}
func NewNumericRangeInclusiveQuery(min, max *float64, minInclusive, maxInclusive *bool) *NumericRangeQuery {
return &NumericRangeQuery{ return &NumericRangeQuery{
Min: min, Min: min,
Max: max, Max: max,
BoostVal: 1.0, InclusiveMin: minInclusive,
InclusiveMax: maxInclusive,
BoostVal: 1.0,
} }
} }
@ -50,7 +58,7 @@ func (q *NumericRangeQuery) Searcher(i *indexImpl, explain bool) (search.Searche
if q.FieldVal == "" { if q.FieldVal == "" {
field = i.m.DefaultField field = i.m.DefaultField
} }
return search.NewNumericRangeSearcher(i.i, q.Min, q.Max, field, q.BoostVal, explain) return search.NewNumericRangeSearcher(i.i, q.Min, q.Max, q.InclusiveMin, q.InclusiveMax, field, q.BoostVal, explain)
} }
func (q *NumericRangeQuery) Validate() error { func (q *NumericRangeQuery) Validate() error {

View File

@ -25,7 +25,7 @@ type NumericRangeSearcher struct {
searcher *DisjunctionSearcher searcher *DisjunctionSearcher
} }
func NewNumericRangeSearcher(index index.Index, min *float64, max *float64, field string, boost float64, explain bool) (*NumericRangeSearcher, error) { func NewNumericRangeSearcher(index index.Index, min *float64, max *float64, inclusiveMin, inclusiveMax *bool, field string, boost float64, explain bool) (*NumericRangeSearcher, error) {
// account for unbounded edges // account for unbounded edges
if min == nil { if min == nil {
negInf := math.Inf(-1) negInf := math.Inf(-1)
@ -35,9 +35,23 @@ func NewNumericRangeSearcher(index index.Index, min *float64, max *float64, fiel
Inf := math.Inf(1) Inf := math.Inf(1)
max = &Inf max = &Inf
} }
if inclusiveMin == nil {
defaultInclusiveMin := true
inclusiveMin = &defaultInclusiveMin
}
if inclusiveMax == nil {
defaultInclusiveMax := false
inclusiveMax = &defaultInclusiveMax
}
// find all the ranges // find all the ranges
minInt64 := numeric_util.Float64ToInt64(*min) minInt64 := numeric_util.Float64ToInt64(*min)
if !*inclusiveMin && minInt64 != math.MaxInt64 {
minInt64 += 1
}
maxInt64 := numeric_util.Float64ToInt64(*max) maxInt64 := numeric_util.Float64ToInt64(*max)
if !*inclusiveMax && maxInt64 != math.MinInt64 {
maxInt64 -= 1
}
// FIXME hard-coded precion, should match field declaration // FIXME hard-coded precion, should match field declaration
termRanges := splitInt64Range(minInt64, maxInt64, 4) termRanges := splitInt64Range(minInt64, maxInt64, 4)
terms := termRanges.Enumerate() terms := termRanges.Enumerate()