From a5d1d7974c8cfb66d2da3d662f2d7ba5d1f30940 Mon Sep 17 00:00:00 2001 From: Marty Schoch Date: Fri, 10 Feb 2017 16:46:38 -0500 Subject: [PATCH] add query support for multi-phrase when parsing json, when we encounter the key "terms", we first try to parse as traditional phrase query, then if that fails, we also try parsing it as multi-phrase --- search/query/multi_phrase.go | 80 +++++++++++++++++++++++++++++++++ search/query/query.go | 8 +++- test/tests/phrase/searches.json | 21 ++++++++- 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 search/query/multi_phrase.go diff --git a/search/query/multi_phrase.go b/search/query/multi_phrase.go new file mode 100644 index 000000000..8a7c9b6ad --- /dev/null +++ b/search/query/multi_phrase.go @@ -0,0 +1,80 @@ +// Copyright (c) 2014 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package query + +import ( + "encoding/json" + "fmt" + + "github.com/blevesearch/bleve/index" + "github.com/blevesearch/bleve/mapping" + "github.com/blevesearch/bleve/search" + "github.com/blevesearch/bleve/search/searcher" +) + +type MultiPhraseQuery struct { + Terms [][]string `json:"terms"` + Field string `json:"field,omitempty"` + BoostVal *Boost `json:"boost,omitempty"` +} + +// NewMultiPhraseQuery creates a new Query for finding +// term phrases in the index. +// It is like PhraseQuery, but each position in the +// phrase may be satisfied by a list of terms +// as opposed to just one. +// At least one of the terms must exist in the correct +// order, at the correct index offsets, in the +// specified field. Queried field must have been indexed with +// IncludeTermVectors set to true. +func NewMultiPhraseQuery(terms [][]string, field string) *MultiPhraseQuery { + return &MultiPhraseQuery{ + Terms: terms, + Field: field, + } +} + +func (q *MultiPhraseQuery) SetBoost(b float64) { + boost := Boost(b) + q.BoostVal = &boost +} + +func (q *MultiPhraseQuery) Boost() float64 { + return q.BoostVal.Value() +} + +func (q *MultiPhraseQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, options search.SearcherOptions) (search.Searcher, error) { + return searcher.NewMultiPhraseSearcher(i, q.Terms, q.Field, options) +} + +func (q *MultiPhraseQuery) Validate() error { + if len(q.Terms) < 1 { + return fmt.Errorf("phrase query must contain at least one term") + } + return nil +} + +func (q *MultiPhraseQuery) UnmarshalJSON(data []byte) error { + type _mphraseQuery MultiPhraseQuery + tmp := _mphraseQuery{} + err := json.Unmarshal(data, &tmp) + if err != nil { + return err + } + q.Terms = tmp.Terms + q.Field = tmp.Field + q.BoostVal = tmp.BoostVal + return nil +} diff --git a/search/query/query.go b/search/query/query.go index 1553f621a..0ac12515d 100644 --- a/search/query/query.go +++ b/search/query/query.go @@ -123,7 +123,13 @@ func ParseQuery(input []byte) (Query, error) { var rv PhraseQuery err := json.Unmarshal(input, &rv) if err != nil { - return nil, err + // now try multi-phrase + var rv2 MultiPhraseQuery + err = json.Unmarshal(input, &rv2) + if err != nil { + return nil, err + } + return &rv2, nil } return &rv, nil } diff --git a/test/tests/phrase/searches.json b/test/tests/phrase/searches.json index 58a4bc0dd..02d23a244 100644 --- a/test/tests/phrase/searches.json +++ b/test/tests/phrase/searches.json @@ -372,5 +372,24 @@ "total_hits": 0, "hits": [] } + }, + { + "comment": "multi-phrase terms", + "search": { + "from": 0, + "size": 10, + "query": { + "field": "body", + "terms": [["twenti","thirti"],["thousand"]] + } + }, + "result": { + "total_hits": 1, + "hits": [ + { + "id": "a" + } + ] + } } -] \ No newline at end of file +]