public Task BuildAsync <T>(QueryBuilderContext <T> ctx) where T : class, new()
        {
            var searchQuery = ctx.GetSourceAs <ISearchQuery>();

            if (searchQuery == null)
            {
                return(Task.CompletedTask);
            }

            if (!String.IsNullOrEmpty(searchQuery.Filter))
            {
                var result = _parser.Parse(searchQuery.Filter);
                searchQuery.Filter = GenerateQueryVisitor.Run(AliasedQueryVisitor.Run(result, _aliasMap, ctx), ctx);

                ctx.Filter &= new QueryFilter {
                    Query = new QueryStringQuery {
                        Query           = searchQuery.Filter,
                        DefaultOperator = Operator.And,
                        AnalyzeWildcard = false
                    }.ToContainer()
                };
            }

            if (!String.IsNullOrEmpty(searchQuery.Criteria))
            {
                var result = _parser.Parse(searchQuery.Criteria);
                searchQuery.Criteria = GenerateQueryVisitor.Run(AliasedQueryVisitor.Run(result, _aliasMap, ctx), ctx);

                ctx.Query &= new QueryStringQuery {
                    Query           = searchQuery.Criteria,
                    DefaultOperator = searchQuery.DefaultCriteriaOperator == SearchOperator.Or ? Operator.Or : Operator.And,
                    AnalyzeWildcard = true
                };
            }

            if (!String.IsNullOrEmpty(searchQuery.Sort))
            {
                var result = _parser.Parse(searchQuery.Sort);
                var opt    = ctx.GetOptionsAs <IElasticQueryOptions>();
                TermToFieldVisitor.Run(result, ctx);
                AliasedQueryVisitor.Run(result, _aliasMap, ctx);
                var fields = GetReferencedFieldsQueryVisitor.Run(result);
                // TODO: Check referenced fields against opt.AllowedSortFields

                var sort = GetSortFieldsVisitor.Run(result, ctx);
                ctx.Search.Sort(sort);
            }

            return(Task.CompletedTask);
        }
        public Task BuildAsync <T>(QueryBuilderContext <T> ctx) where T : class, new()
        {
            string filter = ctx.Source.GetFilterExpression();
            string search = ctx.Source.GetSearchExpression();
            string sort   = ctx.Source.GetSortExpression();

            if (!String.IsNullOrEmpty(filter))
            {
                var result = _parser.Parse(filter);
                filter = GenerateQueryVisitor.Run(AliasedQueryVisitor.Run(result, _aliasMap, ctx), ctx);

                ctx.Filter &= new QueryStringQuery {
                    Query           = filter,
                    DefaultOperator = Operator.And,
                    AnalyzeWildcard = false
                };
            }

            if (!String.IsNullOrEmpty(search))
            {
                var result = _parser.Parse(search);
                search = GenerateQueryVisitor.Run(AliasedQueryVisitor.Run(result, _aliasMap, ctx), ctx);

                ctx.Query &= new QueryStringQuery {
                    Query           = search,
                    DefaultOperator = ctx.Source.GetSearchExpressionDefaultOperator() == SearchOperator.Or ? Operator.Or : Operator.And,
                    AnalyzeWildcard = true
                };
            }

            if (!String.IsNullOrEmpty(sort))
            {
                var result = _parser.Parse(sort);
                var opt    = ctx.Options.GetElasticTypeSettings();
                TermToFieldVisitor.Run(result, ctx);
                AliasedQueryVisitor.Run(result, _aliasMap, ctx);
                var fields = GetReferencedFieldsQueryVisitor.Run(result);
                // TODO: Check referenced fields against opt.AllowedSortFields

                var fieldSort = GetSortFieldsVisitor.Run(result, ctx);
                ctx.Search.Sort(fieldSort);
            }

            return(Task.CompletedTask);
        }