Пример #1
0
Файл: parse.go Проект: deoxxa/qs
// starting point
//   exprList = expr1*
func (p *Parser) parseExprList(ctx context) (bleve.Query, error) {
	// <empty>
	if p.peek().typ == tEOF {
		return bleve.NewMatchNoneQuery(), nil
	}

	must := []bleve.Query{}
	mustNot := []bleve.Query{}
	should := []bleve.Query{}

	for {
		tok := p.peek()
		if tok.typ == tEOF {
			break
		}
		// slightly kludgy...
		if tok.typ == tRPAREN {
			break
		}

		prefix, q, err := p.parseExpr1(ctx)
		if err != nil {
			return nil, err
		}

		switch prefix {
		case tPLUS:
			must = append(must, q)
		case tMINUS:
			mustNot = append(mustNot, q)
		default:
			if p.DefaultOp == AND {
				must = append(must, q)
			} else { // OR
				should = append(should, q)
			}
		}
	}

	total := len(must) + len(mustNot) + len(should)
	if total == 0 {
		return bleve.NewMatchNoneQuery(), nil
	}
	if total == 1 && len(must) == 1 {
		return must[0], nil
	}
	if total == 1 && len(should) == 1 {
		return should[0], nil
	}

	return bleve.NewBooleanQuery(must, should, mustNot), nil
}
Пример #2
0
func (q *allMatchQuery) Searcher(i index.IndexReader, m mapping.IndexMapping, explain bool) (search.Searcher, error) {

	field := q.FieldVal
	if q.FieldVal == "" {
		field = m.DefaultSearchField()
	}
	analyzerName := m.AnalyzerNameForPath(field)
	analyzer := m.AnalyzerNamed(analyzerName)
	tokens := analyzer.Analyze([]byte(q.Match))
	if len(tokens) == 0 {
		noneQuery := bleve.NewMatchNoneQuery()
		return noneQuery.Searcher(i, m, explain)
	}

	tqs := make([]query.Query, len(tokens))
	for i, token := range tokens {
		tq := bleve.NewTermQuery(string(token.Term))
		tq.SetField(field)
		tq.SetBoost(q.BoostVal)
		tqs[i] = tq
	}
	allQuery := bleve.NewConjunctionQuery(tqs...)
	allQuery.SetBoost(q.BoostVal)
	return allQuery.Searcher(i, m, explain)
}
Пример #3
0
// starting point
//   exprList = expr1*
func (p *Parser) parseExprList(ctx context) (query.Query, error) {
	// <empty>
	if p.peek().typ == tEOF {
		return bleve.NewMatchNoneQuery(), nil
	}

	must := []query.Query{}
	mustNot := []query.Query{}
	should := []query.Query{}

	for {
		tok := p.peek()
		if tok.typ == tEOF {
			break
		}
		// slightly kludgy...
		if tok.typ == tRPAREN {
			break
		}

		prefix, q, err := p.parseExpr1(ctx)
		if err != nil {
			return nil, err
		}

		switch prefix {
		case tPLUS:
			must = append(must, q)
		case tMINUS:
			mustNot = append(mustNot, q)
		default:
			if p.DefaultOp == AND {
				must = append(must, q)
			} else { // OR
				should = append(should, q)
			}
		}
	}

	// some obvious shortcuts
	total := len(must) + len(mustNot) + len(should)
	if total == 0 {
		return bleve.NewMatchNoneQuery(), nil
	}
	if total == 1 && len(must) == 1 {
		return must[0], nil
	}
	if total == 1 && len(should) == 1 {
		return should[0], nil
	}

	// no shortcuts - go with the full-fat version
	q := bleve.NewBooleanQuery()
	if len(must) > 0 {
		q.AddMust(must...)
	}
	if len(should) > 0 {
		q.AddShould(should...)
	}
	if len(mustNot) > 0 {
		q.AddMustNot(mustNot...)
	}
	return q, nil
}