public string Compile(QuerySetup query, Facet facet, string facetCode)
        {
            string clauses = String.Join("", facet.Clauses.Select(x => x.Clause));
            string sql     = $@"
               SELECT '{facetCode}' AS facet_code, MIN({facet.CategoryIdExpr}::real) AS min, MAX({facet.CategoryIdExpr}::real) AS max
               FROM {query.Facet.TargetTable.ResolvedSqlJoinName}
                 {query.Joins.Combine("")}
             {"WHERE ".GlueTo(clauses)}";

            return(sql);
        }
        private static void SetupAttachmentFields(QuerySetup querySetup)
        {
            querySetup.SearchFields.Remove(DefaultFields.AttachmentData);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentContent);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentAuthor);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentKeywords);

            querySetup.SearchFields.Add(DefaultFields.AttachmentContent);
            querySetup.SearchFields.Add(DefaultFields.AttachmentAuthor);
            querySetup.SearchFields.Add(DefaultFields.AttachmentKeywords);
        }
Esempio n. 3
0
        public void Search_FromOver10k_Throws()
        {
            var setup = new QuerySetup
            {
                From       = 10001,
                SearchText = GetString(),
                Language   = CultureInfo.CurrentCulture
            };

            Assert.Throws <ArgumentOutOfRangeException>(() => _builder.Search(setup));
        }
        /// <summary>
        /// Mocks IQuerySetupBuilder.Setup. Returns passed argument.
        /// </summary>
        /// <param name="querySetup"></param>
        /// <returns></returns>
        public virtual Mock <IQuerySetupBuilder> MockQuerySetupBuilder(QuerySetup querySetup)
        {
            var mockQuerySetupBuilder = new Mock <IQuerySetupBuilder>();

            mockQuerySetupBuilder.Setup(x => x.Build(
                                            It.IsAny <FacetsConfig2>(),
                                            It.IsAny <Facet>(),
                                            It.IsAny <List <string> >(),
                                            It.IsAny <List <string> >()
                                            )).Returns(querySetup ?? new QuerySetup {
            });
            return(mockQuerySetupBuilder);
        }
Esempio n. 5
0
        public QueryRequest(QuerySetup querySetup)
        {
            querySetup.SearchText.EnsureNotNull(nameof(querySetup.SearchText));
            Query.SearchText = querySetup.SearchText.ToLower();

            _sortFields  = querySetup.SortFields;
            _scriptField = querySetup.ServerVersion >= Core.Constants.InlineVsSourceVersion
                ? JsonNames.ScriptSource
                : JsonNames.Inline;

            From     = querySetup.From;
            Size     = querySetup.Size;
            Operator = querySetup.Operator;
        }
        public void Filter_ReturnsExpectedJsonForDouble(double value)
        {
            var setup = new QuerySetup {
                SearchText = "term", Language = _language
            };

            setup.Filters.Add(new Filter("MyField", value, typeof(double), false, Operator.And));

            var query = (QueryRequest)_builder.TypedSearch <string>(setup);

            var result   = Serialize(query.PostFilter.Bool.Must);
            var expected = GetJsonTestData($"PostFilterShouldDouble_{value}.json");

            Assert.Equal(expected, result, ignoreLineEndingDifferences: true);
        }
        public void Search_IVersionable_WithApplyDefaultFilters_AddsPublishFilters()
        {
            var setup = new QuerySetup
            {
                SearchText          = GetString(),
                Type                = typeof(IVersionable),
                Language            = CultureInfo.CurrentCulture,
                ApplyDefaultFilters = true
            };

            var request = (QueryRequest)_builder.Search(setup);
            var filters = request.Query.Bool.Filter.OfType <Range <DateTime> >();

            Assert.Contains(filters, x => x.RangeSetting.Field == nameof(IVersionable.StopPublish));
            Assert.Contains(filters, x => x.RangeSetting.Field == nameof(IVersionable.StartPublish));
        }
        public void FacetFieldNames_AddsAggregation(string field, MappingType type, string expectedKey)
        {
            var setup = new QuerySetup
            {
                SearchText      = "term",
                Language        = _language,
                FacetFieldNames = new Dictionary <string, MappingType>
                {
                    { field, type }
                }
            };

            var request     = (QueryRequest)_builder.TypedSearch <string>(setup);
            var aggregation = request.Aggregation.First();

            Assert.Equal(expectedKey, aggregation.Key);
        }
        public void FilterACL_AddsBoolShoulds()
        {
            var setup = new QuerySetup
            {
                SearchText       = "term",
                Language         = _language,
                AclPrincipal     = GetPrincipalInfo("foo", "Role1", "Role2"),
                AppendAclFilters = true
            };

            var request   = (QueryRequest)_builder.TypedSearch <string>(setup);
            var boolQuery = request.Query.Bool.Filter.Cast <NestedBoolQuery>().First().Bool;
            var shoulds   = boolQuery.Should.Cast <MatchSimple>();

            Assert.Contains(shoulds, f => f.Match.Value <string>("_acl") == "U:foo");
            Assert.Contains(shoulds, f => f.Match.Value <string>("_acl") == "R:Role1");
            Assert.Contains(shoulds, f => f.Match.Value <string>("_acl") == "R:Role2");
        }
        public void Search_NoScriptScore_ReturnsExpectedJson()
        {
            const string expected1 = "function_score";
            const string expected2 = "\"script_score\":{";

            var builder = new QueryBuilder(null, null, null);

            builder.SetMappedFields(new[] { "bar" });

            var querySetup = new QuerySetup
            {
                SearchText = GetString(),
                Language   = _language
            };

            var result = RemoveWhitespace(Serialize(builder.Search(querySetup)));

            Assert.DoesNotContain(expected1, result);
            Assert.DoesNotContain(expected2, result);
        }
        private static void SetupAttachmentFields(QuerySetup querySetup)
        {
            if (!querySetup.SearchFields.Contains(DefaultFields.Attachment))
            {
                return;
            }

            querySetup.SearchFields.Remove(DefaultFields.Attachment);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentContent);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentAuthor);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentTitle);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentName);
            querySetup.SearchFields.Remove(DefaultFields.AttachmentKeywords);

            querySetup.SearchFields.Add(DefaultFields.AttachmentContent);
            querySetup.SearchFields.Add(DefaultFields.AttachmentAuthor);
            querySetup.SearchFields.Add(DefaultFields.AttachmentTitle);
            querySetup.SearchFields.Add(DefaultFields.AttachmentName);
            querySetup.SearchFields.Add(DefaultFields.AttachmentKeywords);
        }
        public void Search_GaussAndScriptScore_Throws()
        {
            var setup = new QuerySetup
            {
                SearchText  = GetString(),
                ScriptScore = new ScriptScore
                {
                    Script = new ScriptScore.ScriptScoreInner
                    {
                        Language = "painless",
                        Source   = GetString()
                    }
                }
            };

            setup.Gauss.Add(new Gauss());

            Exception exception = Assert.Throws <InvalidOperationException>(() => _builder.Search(setup));

            Assert.Equal("Cannot use Gauss and ScriptScore simultaneously", exception.Message);
        }
        public void Build_WithConcretePickCompilerAndVariousConfigs_GivesExpecteCriteriadCount(string uri)
        {
            // Arrange
            var facetsConfig  = FakeFacetsConfig(uri);
            var pickCriterias = new List <string> {
                "Q1 = Q2", "Q3 = Q4"
            };
            var mockPicksCompiler = MockPicksFilterCompiler(pickCriterias ?? new List <string>());
            var fakeJoins         = FakeJoinsClause(5);
            var mockJoinCompiler  = MockJoinsClauseCompiler(fakeJoins);
            var mockRoutes        = new List <GraphRoute> {
                FakeRoute2("A", "B", "C", "D"),
                FakeRoute2("E", "K")
            };
            var mockFacetsGraph = MockFacetsGraph(mockRoutes);
            var extraTables     = new List <string>();

            // Act
            var builder = new QuerySetupBuilder(mockFacetsGraph.Object, mockPicksCompiler.Object, mockJoinCompiler.Object);

            QuerySetup querySetup = builder.Build(facetsConfig, facetsConfig.TargetFacet, extraTables, null);

            Output.WriteLine($"URI: {uri}");
            foreach (var criteria in querySetup.Criterias)
            {
                Output.WriteLine($" criteria: {criteria}");
            }

            //DumpUriObject(uri, querySetup);

            // Assert

            Assert.Same(facetsConfig.TargetConfig, querySetup.TargetConfig);
            Assert.Same(facetsConfig.TargetFacet, querySetup.Facet);
            // Assert.Equal(mockRoutes.Aggregate(0, (i,z) => i + z.Items.Count), querySetup.Joins.Count);
        }
Esempio n. 14
0
 /// <summary>
 /// A standard freetext search against all fields, constrained by type T. With facets.
 /// </summary>
 /// <param name="querySetup">The QuerySetup. <see cref="QuerySetup"/></param>
 public RequestBase TypedSearch <T>(QuerySetup querySetup) where T : class
 {
     querySetup.Type = typeof(T);
     return(TypedSearch(querySetup));
 }
Esempio n. 15
0
        private static void SetupFilters(QuerySetup setup, QueryRequest request)
        {
            var filterQuery = new NestedBoolQuery();

            // Filter away excluded types
            if (setup.ExcludedTypes.Count > 0)
            {
                filterQuery.Bool.MustNot.AddRange(setup.ExcludedTypes.Select(e => new MatchSimple(DefaultFields.Types, e.GetTypeName().ToLower())));
            }

            foreach (var ex in GetExcludedRoots(setup))
            {
                filterQuery.Bool.MustNot.Add(new MatchSimple(DefaultFields.Id, ex.Key.ToString()));

                if (ex.Value)
                {
                    filterQuery.Bool.MustNot.Add(new MatchSimple(DefaultFields.Path, ex.Key.ToString()));
                }
            }

            // Filter on type
            if (setup.Type != null)
            {
                var term = CreateTerm(new Filter(DefaultFields.Types, setup.Type.GetTypeName().ToLower(), null, false, Operator.And));
                filterQuery.Bool.Must.Add(term);
            }

            // Filter on ranges
            if (setup.Ranges.Count > 0)
            {
                request.Query.Bool.Filter.AddRange(setup.Ranges);
            }

            // Filter on root-id
            if (setup.RootId != 0)
            {
                var term = new Term(DefaultFields.Path, Convert.ToString(setup.RootId), true);
                filterQuery.Bool.Must.Add(term);
            }

            // Filter on ACL
            if (setup.AppendAclFilters && setup.AclPrincipal != null)
            {
                var boolQuery = new NestedBoolQuery();

                foreach (var role in setup.AclPrincipal.RoleList)
                {
                    var roleTerm = new MatchSimple(DefaultFields.Acl, $"R:{role}");
                    boolQuery.Bool.Should.Add(roleTerm);
                }

                var userTerm = new MatchSimple(DefaultFields.Acl, $"U:{setup.AclPrincipal.Name}");
                boolQuery.Bool.Should.Add(userTerm);

                boolQuery.Bool.MinimumNumberShouldMatch = 1;

                request.Query.Bool.Filter.Add(boolQuery);
            }

            if (setup.FilterGroups.Count > 0)
            {
                foreach (var filterGroup in setup.FilterGroups)
                {
                    foreach (var filter in filterGroup.Value.Filters)
                    {
                        var boolQuery = new BoolQuery();
                        if (filter.Operator == Operator.Or)
                        {
                            boolQuery.MinimumNumberShouldMatch = 1;
                            boolQuery.Should = new List <MatchBase>();

                            if (ArrayHelper.IsArrayCandidate(filter.Value.GetType()))
                            {
                                foreach (object value in (IEnumerable)ArrayHelper.ToArray(filter.Value))
                                {
                                    boolQuery.Should.Add(Term.FromFilter(filter, value));
                                }
                            }
                            else
                            {
                                boolQuery.Should.Add(Term.FromFilter(filter));
                            }
                        }
                        else if (filter.Operator == Operator.And)
                        {
                            boolQuery.Must = new List <MatchBase>();

                            if (ArrayHelper.IsArrayCandidate(filter.Value.GetType()))
                            {
                                foreach (object value in (IEnumerable)ArrayHelper.ToArray(filter.Value))
                                {
                                    boolQuery.Must.Add(Term.FromFilter(filter, value));
                                }
                            }
                            else
                            {
                                boolQuery.Must.Add(Term.FromFilter(filter));
                            }
                        }

                        // Use regular or post filter?
                        if (!setup.UsePostfilters)
                        {
                            request.Query.Bool.Filter.Add(Term.FromArrayFilter(filter));
                        }
                        else
                        {
                            if (filterGroup.Value.Operator == Operator.And)
                            {
                                request.PostFilter.Bool.Must.Add(new NestedBoolQuery(boolQuery));
                            }
                            else if (filterGroup.Value.Operator == Operator.Or)
                            {
                                request.PostFilter.Bool.Should.Add(new NestedBoolQuery(boolQuery));
                            }
                        }
                    }
                }
            }

            if (setup.Filters.Count > 0)
            {
                // Add not-filters as regular filter regardless of post-filter value
                IEnumerable <Filter> notFilters = setup.Filters.Where(f => f.Not).ToArray();
                filterQuery.Bool.MustNot.AddRange(notFilters.Select(CreateTerm));

                // Use regular or post filter?
                if (!setup.UsePostfilters)
                {
                    request.Query.Bool.Filter.AddRange(
                        setup.Filters
                        .Except(notFilters)
                        .Select(CreateTerm));
                }
                else
                {
                    request.PostFilter.Bool.Must.AddRange(
                        setup.Filters
                        .Except(notFilters)
                        .Where(f => f.Operator == Operator.And && !f.Not)
                        .Select(CreateTerm));

                    request.PostFilter.Bool.Should.AddRange(
                        setup.Filters
                        .Except(notFilters)
                        .Where(f => f.Operator == Operator.Or && !f.Not)
                        .Select(CreateTerm));
                }
            }

            if (filterQuery.HasAnyValues())
            {
                request.Query.Bool.Filter.Add(filterQuery);
            }

            AppendDefaultFilters(request.Query, setup.Type);

            if (request.Query.Bool.Should.Count > 1 && request.Query.Bool.Must.Count == 0)
            {
                request.Query.Bool.MinimumNumberShouldMatch = 1;
            }
            else
            {
                request.Query.Bool.MinimumNumberShouldMatch = null;
            }

            if (request.PostFilter.Bool.Should.Count > 0 && request.PostFilter.Bool.Must.Count == 0)
            {
                request.PostFilter.Bool.MinimumNumberShouldMatch = 1;
            }
            else
            {
                request.PostFilter.Bool.MinimumNumberShouldMatch = null;
            }
        }
Esempio n. 16
0
        private void SetupBoosting(QuerySetup setup, QueryRequest request)
        {
            if (!setup.UseBoosting)
            {
                return;
            }

            List <Boost> boosting = GetBoosting(setup.Type, setup.BoostFields);

            if (boosting.Count > 0)
            {
                var searchText = request.Query.SearchText.Replace("*", String.Empty);
                if (!TextUtil.IsNumeric(searchText))
                {
                    boosting.RemoveAll(b => b.FieldName.Equals(DefaultFields.Id));
                }

                request.Query.Bool.Should.AddRange(
                    boosting.Select(b =>
                                    new MatchWithBoost(b.FieldName,
                                                       searchText, b.Weight, setup.Operator)));
            }

            // Boosting by type
            if (setup.BoostTypes.Count > 0)
            {
                request.Query.Bool.Should.AddRange(
                    setup.BoostTypes.Select(b =>
                                            new MatchWithBoost(DefaultFields.Types, b.Key.GetTypeName(), b.Value, setup.Operator)));

                // Direct match in Type gives higher score than match in Types, hence the +1
                request.Query.Bool.Should.AddRange(
                    setup.BoostTypes.Select(b =>
                                            new MatchWithBoost(DefaultFields.Type, b.Key.GetTypeName(), b.Value + 1, setup.Operator)));
            }

            if (setup.BoostAncestors.Count > 0)
            {
                request.Query.Bool.Should.AddRange(
                    setup.BoostAncestors.Select(b =>
                                                new MatchWithBoost(DefaultFields.Path, b.Key.ToString(), b.Value, setup.Operator)));

                request.Query.Bool.Should.AddRange(
                    setup.BoostAncestors.Select(b =>
                                                new MatchWithBoost(DefaultFields.Id, b.Key.ToString(), b.Value, setup.Operator)));
            }

            // Best Bets
            if (setup.UseBestBets && !String.IsNullOrWhiteSpace(request.Query.SearchText))
            {
                IEnumerable <string> terms = request.Query.SearchText
                                             .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                                             .Select(t => t.Trim().Trim('*'));

                var key = setup.IndexName ?? _settings.GetDefaultIndexName(Language.GetLanguageCode(setup.Language));

                if (!Conventions.Indexing.BestBets.TryGetValue(key, out var bestBetsForLanguage))
                {
                    return;
                }

                IEnumerable <BestBet> bestBets = bestBetsForLanguage
                                                 .Where(b => b.Terms.Any(t => terms.Contains(t)));

                request.Query.Bool.Should.AddRange(
                    bestBets.Select(_ =>
                                    new MatchWithBoost(
                                        DefaultFields.BestBets, request.Query.SearchText.Trim('*'), BestBetMultiplier, setup.Operator)));
            }
        }
Esempio n. 17
0
        private RequestBase SearchInternal(QuerySetup setup)
        {
            _searchType = setup.SearchType;

            setup.SearchText.EnsureNotNull("searchText");

            if (setup.From > 10000 || setup.Size > 10000)
            {
                throw new ArgumentOutOfRangeException(nameof(setup),
                                                      "From (skip) and size (take) must be less than or equal to: 10000. If you really must, this limit can be set by changing the [index.max_result_window] index level parameter");
            }

            var request = new QueryRequest(setup);

            request.Query.SearchText = setup.SearchText.ToLower();

            if (setup.SearchFields.Count == 0)
            {
                setup.SearchFields.AddRange(GetMappedFields(Language.GetLanguageCode(setup.Language), setup.IndexName, setup.SearchType));
            }

            if (Log.IsDebugEnabled())
            {
                Log.Debug("SearchFields:");
                setup.SearchFields.ForEach(f => Log.Debug(f));
            }

            SetupAttachmentFields(setup);
            SetupSourceFields(request, setup);

            if (setup.IsGetQuery)
            {
                request.Query.Bool.Must.Add(new MatchAll());
            }
            else if (setup.IsWildcard)
            {
                setup.SearchFields.ForEach(field =>
                                           request.Query.Bool.Should.Add(new Wildcard(field, request.Query.SearchText)));

                // Boost hits that starts with searchtext, ie. when searching for "*foo*",
                // hits on "foobar" will score higher than hits on "barfoo"
                if (request.Query.SearchText.StartsWith("*"))
                {
                    setup.SearchFields.ForEach(field =>
                                               request.Query.Bool.Should.Add(new Wildcard(field, request.Query.SearchText.TrimStart('*'), 10)));
                }

                request.Query.Bool.MinimumNumberShouldMatch = 1;
            }
            else
            {
                request.Query.Bool.Must.Add(
                    new MatchMulti(
                        request.Query.SearchText,
                        setup.SearchFields,
                        setup.Operator,
                        null,
                        null,
                        setup.FuzzyLength,
                        setup.Analyzer));

                // Boost phrase matches if multiple words
                if (request.Query.SearchText?.IndexOf(" ", StringComparison.OrdinalIgnoreCase) > 0)
                {
                    request.Query.Bool.Should.Add(
                        new MatchMulti(
                            request.Query.SearchText,
                            setup.SearchFields,
                            setup.Operator,
                            "phrase",
                            2));
                }
            }

            SetupBoosting(setup, request);

            if (setup.FacetFieldNames.Count > 0)
            {
                request.Aggregation = GetAggregationQuery(setup.FacetFieldNames);
            }

            SetupFilters(setup, request);

            // Highlighting
            if (setup.UseHighlight)
            {
                request.Highlight = new Highlight
                {
                    Fields = GetHighlightFields()
                };
            }

            // Did-you-mean
            if (setup.EnableDidYouMean)
            {
                request.DidYouMeanSuggest = new DidYouMeanSuggest(request.Query.SearchText);
            }

            // function_score. Must be the last operation in this method.
            // Cannot use Gauss and ScriptScore simultaneously
            if (setup.ScriptScore != null && setup.Gauss.Count > 0)
            {
                throw new Exception("Cannot use Gauss and ScriptScore simultaneously");
            }

            if (setup.ScriptScore != null)
            {
                request.Query = new FunctionScoreQuery(request.Query, setup.ScriptScore);
            }

            if (setup.Gauss.Count > 0)
            {
                request.Query = new FunctionScoreQuery(request.Query, setup.Gauss);
            }

            return(request);
        }
Esempio n. 18
0
 internal RequestBase MoreLikeThis(QuerySetup setup)
 {
     return(new MoreLikeThisRequest(setup));
 }
Esempio n. 19
0
 internal RequestBase MoreLikeThis(QuerySetup setup)
 => new MoreLikeThisRequest(setup);
 /// <summary>
 /// See https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html
 /// </summary>
 public SuggestRequest Suggest(QuerySetup querySetup)
 {
     return(new SuggestRequest(querySetup.SearchText, querySetup.Size));
 }
Esempio n. 21
0
 /// <summary>
 /// A standard freetext search against all fields
 /// </summary>
 /// <param name="querySetup">The QuerySetup. <see cref="QuerySetup"/></param>
 public RequestBase Search(QuerySetup querySetup)
 {
     return(SearchInternal(querySetup));
 }
Esempio n. 22
0
 /// <summary>
 /// A standard freetext search against all fields
 /// </summary>
 /// <param name="querySetup">The QuerySetup. <see cref="QuerySetup"/></param>
 public RequestBase Search(QuerySetup querySetup)
 => SearchInternal(querySetup);
Esempio n. 23
0
        private RequestBase SearchInternal(QuerySetup setup)
        {
            CheckSize(setup);

            var request = new QueryRequest(setup);

            if (setup.SearchFields.Count == 0)
            {
                setup.SearchFields.AddRange(GetMappedFields(Language.GetLanguageCode(setup.Language), setup.IndexName, setup.SearchType));
            }

            if (_logger.IsDebugEnabled())
            {
                _logger.Debug("SearchFields:");
                setup.SearchFields.ForEach(f => _logger.Debug(f));
            }

            SetupAttachmentFields(setup);
            SetupSourceFields(request, setup);

            if (setup.IsGetQuery)
            {
                request.Query.Bool.Must.Add(new MatchAll());
            }
            else if (setup.IsWildcard)
            {
                setup.SearchFields.ForEach(field =>
                                           request.Query.Bool.Should.Add(new Wildcard(field, request.Query.SearchText)));

                // Boost hits that starts with searchtext, ie. when searching for "*foo*",
                // hits on "foobar" will score higher than hits on "barfoo"
                if (request.Query.SearchText.StartsWith("*"))
                {
                    setup.SearchFields.ForEach(field =>
                                               request.Query.Bool.Should.Add(new Wildcard(field, request.Query.SearchText.TrimStart('*'), 10)));
                }

                request.Query.Bool.MinimumNumberShouldMatch = 1;
            }
            else
            {
                request.Query.Bool.Must.Add(
                    new MatchMulti(
                        request.Query.SearchText,
                        setup.SearchFields,
                        setup.Operator,
                        null,
                        null,
                        setup.FuzzyLength,
                        setup.Analyzer));

                // Boost phrase matches if multiple words
                if (request.Query.SearchText?.IndexOf(" ", StringComparison.OrdinalIgnoreCase) > 0)
                {
                    request.Query.Bool.Should.Add(
                        new MatchMulti(
                            request.Query.SearchText,
                            setup.SearchFields,
                            setup.Operator,
                            "phrase",
                            2));
                }
            }

            SetupBoosting(setup, request);

            if (setup.FacetFieldNames.Count > 0)
            {
                request.Aggregation = GetAggregationQuery(setup.FacetFieldNames);
            }

            SetupFilters(setup, request);

            // Highlighting
            if (setup.UseHighlight)
            {
                request.Highlight = new Highlight
                {
                    Fields = GetHighlightFields()
                };
            }

            // Did-you-mean
            if (setup.EnableDidYouMean)
            {
                request.DidYouMeanSuggest = new DidYouMeanSuggest(request.Query.SearchText);
            }

            // function_score. Must be the last operation in this method.
            // Cannot use Gauss and ScriptScore simultaneously
            if (setup.ScriptScore != null && setup.Gauss.Count > 0)
            {
                throw new InvalidOperationException("Cannot use Gauss and ScriptScore simultaneously");
            }

            if (setup.ScriptScore != null)
            {
                request.Query = new FunctionScoreQuery(request.Query, setup.ScriptScore);
            }

            if (setup.Gauss.Count > 0)
            {
                request.Query = new FunctionScoreQuery(request.Query, setup.Gauss);
            }

            return(request);
        }