Tune and test QueryParser Go bindings.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/8b99de01 Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/8b99de01 Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/8b99de01 Branch: refs/heads/master Commit: 8b99de01d90fdb011286e8739815ddda6b9d05fd Parents: 3d85838 Author: Marvin Humphrey <[email protected]> Authored: Mon Dec 21 17:29:59 2015 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Tue Dec 22 11:54:53 2015 -0800 ---------------------------------------------------------------------- go/build.go | 8 +++++ go/lucy/search.go | 41 +++++++++++++++++++++++ go/lucy/search_test.go | 79 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/8b99de01/go/build.go ---------------------------------------------------------------------- diff --git a/go/build.go b/go/build.go index 692702d..2c9ef95 100644 --- a/go/build.go +++ b/go/build.go @@ -236,6 +236,14 @@ func specClasses(parcel *cfc.Parcel) { searcherBinding.SpecMethod("", "ReadDoc(int32, interface{}) error") searcherBinding.Register() + qParserBinding := cfc.NewGoClass(parcel, "Lucy::Search::QueryParser") + qParserBinding.SetSuppressCtor(true) + qParserBinding.SpecMethod("Make_Phrase_Query", "MakePhraseQuery(string, []interface{}) PhraseQuery") + qParserBinding.SpecMethod("Make_AND_Query", "MakeANDQuery([]Query) ANDQuery") + qParserBinding.SpecMethod("Make_OR_Query", "MakeORQuery([]Query) ORQuery") + qParserBinding.SpecMethod("Get_Fields", "getFields() []string") + qParserBinding.Register() + hitsBinding := cfc.NewGoClass(parcel, "Lucy::Search::Hits") hitsBinding.SpecMethod("Next", "Next(hit interface{}) bool") hitsBinding.SpecMethod("", "Error() error") http://git-wip-us.apache.org/repos/asf/lucy/blob/8b99de01/go/lucy/search.go ---------------------------------------------------------------------- diff --git a/go/lucy/search.go b/go/lucy/search.go index e202b9d..75c4055 100644 --- a/go/lucy/search.go +++ b/go/lucy/search.go @@ -27,6 +27,7 @@ package lucy #include "Lucy/Search/Query.h" #include "Lucy/Search/Compiler.h" #include "Lucy/Search/Searcher.h" +#include "Lucy/Search/QueryParser.h" #include "Lucy/Search/ANDQuery.h" #include "Lucy/Search/ORQuery.h" #include "Lucy/Search/ANDMatcher.h" @@ -146,6 +147,46 @@ func (s *SearcherIMP) topDocs(query Query, numWanted uint32, return topDocs, err } +func NewQueryParser(schema Schema, fields []string) QueryParser { + return NewORParser(schema, fields) +} + +func NewORParser(schema Schema, fields []string) QueryParser { + return doNewQueryParser(schema, "OR", fields) +} + +func NewANDParser(schema Schema, fields []string) QueryParser { + return doNewQueryParser(schema, "AND", fields) +} + +func doNewQueryParser(schema Schema, defaultBoolop string, fields []string) QueryParser { + schemaCF := (*C.lucy_Schema)(clownfish.Unwrap(schema, "schema")) + defaultBoolopCF := (*C.cfish_String)(clownfish.GoToClownfish(defaultBoolop, unsafe.Pointer(C.CFISH_STRING), true)) + defer C.cfish_decref(unsafe.Pointer(defaultBoolopCF)) + fieldsCF := stringSliceToVec(fields) + defer C.cfish_decref(unsafe.Pointer(fieldsCF)) + retvalCF := C.lucy_QParser_new(schemaCF, nil, defaultBoolopCF, fieldsCF) + return clownfish.WRAPAny(unsafe.Pointer(retvalCF)).(QueryParser) +} + +func (qp *QueryParserIMP) MakePhraseQuery(field string, terms []interface{}) PhraseQuery { + return NewPhraseQuery(field, terms) +} + +func (qp *QueryParserIMP) MakeANDQuery(children []Query) ANDQuery { + return NewANDQuery(children) +} + +func (qp *QueryParserIMP) MakeORQuery(children []Query) ORQuery { + return NewORQuery(children) +} + +func (q *QueryParserIMP) getFields() []string { + self := (*C.lucy_QueryParser)(clownfish.Unwrap(q, "q")) + retvalCF := C.LUCY_QParser_Get_Fields(self) + return vecToStringSlice(retvalCF) +} + type setScorer interface { SetScore(float32) } http://git-wip-us.apache.org/repos/asf/lucy/blob/8b99de01/go/lucy/search_test.go ---------------------------------------------------------------------- diff --git a/go/lucy/search_test.go b/go/lucy/search_test.go index 3d4fc50..7c844d3 100644 --- a/go/lucy/search_test.go +++ b/go/lucy/search_test.go @@ -723,3 +723,82 @@ func TestMatchDocSerialization(t *testing.T) { t.Errorf("Failed round-trip serializetion of MatchDoc") } } + +func TestQueryParserConstructors(t *testing.T) { + schema := createTestSchema() + qParser := NewQueryParser(schema, nil) + if _, ok := qParser.Parse("foo bar").(ORQuery); !ok { + t.Errorf("qParser boolop") + } + orParser := NewORParser(schema, nil) + if _, ok := orParser.Parse("foo bar").(ORQuery); !ok { + t.Errorf("orParser boolop") + } + andParser := NewANDParser(schema, nil) + if _, ok := andParser.Parse("foo bar").(ANDQuery); !ok { + t.Errorf("andParser boolop") + } +} + +func TestQueryParserFactories(t *testing.T) { + qParser := NewQueryParser(createTestSchema(), nil) + if _, ok := qParser.MakeTermQuery("content", "foo").(TermQuery); !ok { + t.Errorf("MakeTermQuery") + } + if _, ok := qParser.MakePhraseQuery("content", []interface{}{}).(PhraseQuery); !ok { + t.Errorf("MakePhraseQuery") + } + if _, ok := qParser.MakeORQuery([]Query{}).(ORQuery); !ok { + t.Errorf("MakeORQuery") + } + if _, ok := qParser.MakeANDQuery([]Query{}).(ANDQuery); !ok { + t.Errorf("MakeANDQuery") + } + if _, ok := qParser.MakeNOTQuery(NewTermQuery("content", "foo")).(NOTQuery); !ok { + t.Errorf("MakeNOTQuery") + } + req := NewTermQuery("content", "foo") + opt := NewTermQuery("content", "bar") + if _, ok := qParser.MakeReqOptQuery(req, opt).(RequiredOptionalQuery); !ok { + t.Errorf("MakeReqOptQuery") + } +} + +func TestQueryParserParsing(t *testing.T) { + qParser := NewQueryParser(createTestSchema(), nil) + if _, ok := qParser.Parse("foo").(Query); !ok { + t.Errorf("Parse") + } + if _, ok := qParser.Tree("foo").(Query); !ok { + t.Errorf("Tree") + } + if _, ok := qParser.Expand(NewTermQuery("content", "foo")).(Query); !ok { + t.Errorf("Expand") + } + if _, ok := qParser.ExpandLeaf(NewLeafQuery("content", "foo")).(Query); !ok { + t.Errorf("ExpandLeaf") + } + if _, ok := qParser.Prune(NewTermQuery("content", "foo")).(Query); !ok { + t.Errorf("Prune") + } +} + +func TestQueryParserAccessors(t *testing.T) { + qParser := NewQueryParser(createTestSchema(), nil) + if got := qParser.getAnalyzer(); got != nil { + t.Errorf("getAnalyzer") + } + if got := qParser.getSchema(); got == nil { + t.Errorf("getSchema") + } + if got := qParser.getFields(); !reflect.DeepEqual(got, []string{"content"}) { + t.Errorf("getFields") + } + if got := qParser.getDefaultBoolOp(); got != "OR" { + t.Errorf("getDefaultBoolOp") + } + qParser.SetHeedColons(true) + if !qParser.heedColons() { + t.Errorf("SetHeedColons/heedColons") + } +}
