Ejemplo n.º 1
0
        private static IQueryPart CreateQueryPart(
            IIndexedFieldLookup fieldLookup,
            QueryParserState state,
            QueryToken token,
            ITokenizer wordTokenizer,
            IQueryPart?currentQuery)
        {
            switch (token.TokenType)
            {
            case QueryTokenType.Text:
                return(ComposePart(currentQuery, CreateWordPart(token, wordTokenizer)));

            case QueryTokenType.FieldFilter:
                var(fieldId, tokenizer) = fieldLookup.GetFieldInfo(token.TokenText);
                var filteredPart = CreateQueryPart(fieldLookup, state, state.GetNextToken(), tokenizer, null);
                return(ComposePart(
                           currentQuery,
                           new FieldFilterQueryOperator(token.TokenText, fieldId, filteredPart)));



            case QueryTokenType.OrOperator:
            case QueryTokenType.AndOperator:
            case QueryTokenType.NearOperator:
            case QueryTokenType.PrecedingNearOperator:
            case QueryTokenType.PrecedingOperator:
                var rightPart = CreateQueryPart(fieldLookup, state, state.GetNextToken(), wordTokenizer, null);
                return(CombineParts(currentQuery, rightPart, token.TokenType, token.Tolerance));

            case QueryTokenType.OpenBracket:
                var bracketedPart = state.GetTokensUntil(QueryTokenType.CloseBracket)
                                    .Aggregate((IQueryPart?)null, (current, next) => CreateQueryPart(fieldLookup, state, next, wordTokenizer, current));

                if (bracketedPart == null)
                {
                    throw new QueryParserException(ExceptionMessages.EmptyBracketedExpressionsAreNotSupported);
                }

                return(ComposePart(currentQuery, new BracketedQueryPart(bracketedPart)));

            case QueryTokenType.BeginAdjacentTextOperator:
                var words = state.GetTokensUntil(QueryTokenType.EndAdjacentTextOperator)
                            .SelectMany(t => CreateWordParts(t, wordTokenizer))
                            .ToList();

                if (words.Count == 0)
                {
                    throw new QueryParserException(ExceptionMessages.EmptyAdjacentTextPartsAreNotSupported);
                }

                return(ComposePart(currentQuery, new AdjacentWordsQueryOperator(words)));

            default:
                throw new QueryParserException(ExceptionMessages.UnexpectedTokenEncountered, token.TokenType);
            }
        }
Ejemplo n.º 2
0
        public IQuery Parse(IIndexedFieldLookup fieldLookup, string queryText, ITokenizer wordTokenizer)
        {
            if (fieldLookup is null)
            {
                throw new ArgumentNullException(nameof(fieldLookup));
            }

            IQueryPart?rootPart = null;

            var state = new QueryParserState(queryText);

            while (state.TryGetNextToken(out var token))
            {
                rootPart = CreateQueryPart(fieldLookup, state, token, wordTokenizer, rootPart);
            }

            return(new Query(rootPart ?? EmptyQueryPart.Instance));
        }
Ejemplo n.º 3
0
        private static IQueryPart CreateQueryPart(
            IIndexedFieldLookup fieldLookup,
            QueryParserState state,
            QueryToken token,
            ITokenizer wordTokenizer,
            IQueryPart rootPart)
        {
            switch (token.TokenType)
            {
            case QueryTokenType.Text:
                return(ComposePart(rootPart, CreateWordPart(token, wordTokenizer)));

            case QueryTokenType.FieldFilter:
                var filteredPart = CreateQueryPart(fieldLookup, state, state.GetNextToken(), wordTokenizer, null);
                if (fieldLookup.TryGetIdForField(token.TokenText, out var fieldId))
                {
                    return(ComposePart(
                               rootPart,
                               new FieldFilterQueryOperator(token.TokenText, fieldId, filteredPart)));
                }

                throw new QueryParserException(ExceptionMessages.UnknownFieldReference, token.TokenText);

            case QueryTokenType.OrOperator:
            case QueryTokenType.AndOperator:
            case QueryTokenType.NearOperator:
            case QueryTokenType.PrecedingNearOperator:
            case QueryTokenType.PrecedingOperator:
                var rightPart = CreateQueryPart(fieldLookup, state, state.GetNextToken(), wordTokenizer, null);
                return(CombineParts(rootPart, rightPart, token.TokenType, token.Tolerance));

            case QueryTokenType.OpenBracket:
                var bracketedPart = state.GetTokensUntil(QueryTokenType.CloseBracket)
                                    .Aggregate((IQueryPart)null, (current, next) => CreateQueryPart(fieldLookup, state, next, wordTokenizer, current));

                return(bracketedPart == null
                               ? rootPart
                               : ComposePart(rootPart, new BracketedQueryPart(bracketedPart)));

            default:
                throw new QueryParserException(ExceptionMessages.UnexpectedTokenEncountered, token.TokenType);
            }
        }