Beispiel #1
0
        public void Search_ShouldSearchByCombination()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber          = 2,
                PageSize            = 50,
                VacancyLocationType = VacancyLocationType.NonNational,
                StandardLarsCodes   = new List <string> {
                    "123", "124"
                },
                FrameworkLarsCodes = new List <string> {
                    "502", "501"
                },
                Latitude     = 52.4088862063274,
                Longitude    = 1.50554768088033,
                Ukprn        = 12345678,
                SearchRadius = 40,
                FromDate     = DateTime.Parse("2018-11-24"),
                SortType     = VacancySearchSortType.ExpectedStartDate
            };

            const string expectedJsonQuery = "{\"from\":50,\"query\":{\"bool\":{\"filter\":[{\"geo_distance\":{\"distance\":\"40mi\",\"location\":{\"lat\":52.4088862063274,\"lon\":1.50554768088033}}}],\"must\":[{\"bool\":{\"should\":[{\"terms\":{\"frameworkLarsCode\":[\"502\",\"501\"]}},{\"terms\":{\"standardLarsCode\":[\"123\",\"124\"]}}]}},{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}},{\"range\":{\"postedDate\":{\"gte\":\"2018-11-24T00:00:00\"}}},{\"match\":{\"ukprn\":{\"query\":\"12345678\"}}}]}},\"size\":50,\"sort\":[{\"startDate\":{\"order\":\"asc\"}},{\"vacancyReference\":{\"order\":\"asc\"}},{\"_geo_distance\":{\"distance_type\":\"arc\",\"location\":[{\"lat\":52.4088862063274,\"lon\":1.50554768088033}],\"unit\":\"mi\"}}],\"track_scores\":true}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #2
0
 private void ValidateSearchParameters(ApprenticeshipSearchRequestParameters parameters)
 {
     if ((parameters.PageNumber - 1) * parameters.PageSize >= 10000)
     {
         throw new InvalidOperationException("Search cannot return more than 10000 records, please use filters to narrow down your search.");
     }
 }
Beispiel #3
0
        private ISearchResponse <ApprenticeshipSearchResult> PerformSearch(ApprenticeshipSearchRequestParameters parameters)
        {
            var results = _elasticClient.Search <ApprenticeshipSearchResult>(s =>
            {
                s.Index(_indexName);
                s.Skip((parameters.PageNumber - 1) * parameters.PageSize);
                s.Take(parameters.PageSize);

                s.TrackScores();

                s.Query(q => GetQuery(parameters, q));

                SetSort(s, parameters);

                if (parameters.CalculateSubCategoryAggregations)
                {
                    s.Aggregations(a => a.Terms(SubCategoriesAggregationName, st => st.Field(o => o.SubCategoryCode)));
                }

                //Filters to run after the aggregations have been calculated
                if (parameters.SubCategoryCodes != null && parameters.SubCategoryCodes.Any())
                {
                    s.PostFilter(ff => ff.Terms(f =>
                                                f.Field(g => g.SubCategoryCode)
                                                .Terms(parameters.SubCategoryCodes.Distinct())));
                }

                return(s);
            });

            SetHitValuesOnSearchResults(parameters, results);

            return(results);
        }
Beispiel #4
0
 public ApprenticeshipSearchResponse(
     long total,
     IEnumerable <ApprenticeshipSearchResult> results,
     IEnumerable <AggregationResult> aggregationResults,
     ApprenticeshipSearchRequestParameters searchParameters)
 {
     Total              = total;
     Results            = results;
     AggregationResults = aggregationResults;
     SearchParameters   = searchParameters;
 }
Beispiel #5
0
        public void Search_ShouldSearchByVacancyReference()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber       = 1,
                PageSize         = 1,
                VacancyReference = "123456789"
            };

            const string expectedJsonQuery = "{\"from\":0,\"query\":{\"bool\":{\"filter\":[{\"term\":{\"vacancyReference\":{\"value\":\"123456789\"}}}]}},\"size\":1,\"sort\":[{\"_score\":{\"order\":\"desc\"}}],\"track_scores\":true}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #6
0
        public ApprenticeshipSearchResponse Search(ApprenticeshipSearchRequestParameters searchParameters)
        {
            SanitizeSearchParameters(searchParameters);
            ValidateSearchParameters(searchParameters);

            var results = PerformSearch(searchParameters);

            var aggregationResults = searchParameters.CalculateSubCategoryAggregations ?
                                     GetAggregationResultsFrom(results.Aggregations) :
                                     null;
            var response = new ApprenticeshipSearchResponse(results.Total, results.Documents, aggregationResults, searchParameters);

            return(response);
        }
Beispiel #7
0
        public void Search_ShouldSearchByNationwideOnly()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber          = 1,
                PageSize            = 100,
                VacancyLocationType = VacancyLocationType.National,
                SortType            = VacancySearchSortType.RecentlyAdded
            };

            const string expectedJsonQuery = "{\"from\":0,\"size\":100,\"track_scores\":true,\"sort\":[{\"postedDate\":{\"order\":\"desc\"}},{\"vacancyReference\":{\"order\":\"desc\"}}],\"query\":{\"match\":{\"vacancyLocationType\":{\"query\":\"National\"}}}}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #8
0
        private static int GetGeoDistanceSortHitPosition(ApprenticeshipSearchRequestParameters searchParameters)
        {
            switch (searchParameters.SortType)
            {
            case VacancySearchSortType.ExpectedStartDate:
                return(2);

            case VacancySearchSortType.Distance:
                return(0);

            default:
                return(1);
            }
        }
Beispiel #9
0
        private void SanitizeSearchParameters(ApprenticeshipSearchRequestParameters parameters)
        {
            if (string.IsNullOrEmpty(parameters.Keywords))
            {
                return;
            }

            parameters.Keywords = parameters.Keywords.ToLower();

            foreach (var excludedTerm in _keywordExcludedTerms)
            {
                parameters.Keywords = parameters.Keywords.Replace(excludedTerm, "");
            }
        }
Beispiel #10
0
        public void Search_ShouldSearchBySubCategoryCode()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber       = 1,
                PageSize         = 5,
                SubCategoryCodes = new[] { "sub-code" },
                CalculateSubCategoryAggregations = true
            };

            const string expectedJsonQuery = "{\"aggs\":{\"SubCategoryCodes\":{\"terms\":{\"field\":\"subCategoryCode\"}}},\"from\":0,\"post_filter\":{\"terms\":{\"subCategoryCode\":[\"sub-code\"]}},\"size\":5,\"sort\":[{\"_score\":{\"order\":\"desc\"}}],\"track_scores\":true}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #11
0
        public void Search_ShouldSearchByPostedInLastNumberOfDays()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber          = 1,
                PageSize            = 100,
                VacancyLocationType = VacancyLocationType.NonNational,
                FromDate            = DateTime.Parse("2018-12-01"),
                SortType            = VacancySearchSortType.RecentlyAdded
            };

            const string expectedJsonQuery = "{\"from\":0,\"size\":100,\"track_scores\":true,\"sort\":[{\"postedDate\":{\"order\":\"desc\"}},{\"vacancyReference\":{\"order\":\"desc\"}}],\"query\":{\"bool\":{\"must\":[{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}},{\"range\":{\"postedDate\":{\"gte\":\"2018-12-01T00:00:00\"}}}]}}}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #12
0
        public void Search_ShouldSearchByApprenticeshipLevelIfNotAll()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                ApprenticeshipLevel = "Advanced",
                PageNumber          = 1,
                PageSize            = 5,
                SearchField         = ApprenticeshipSearchField.All,
                SortType            = VacancySearchSortType.ClosingDate,
                VacancyLocationType = VacancyLocationType.National
            };

            const string expectedJsonQuery = "{\"from\":0,\"size\":5,\"track_scores\":true,\"sort\":[{\"closingDate\":{\"order\":\"asc\"}}],\"query\":{\"bool\":{\"must\":[{\"match\":{\"vacancyLocationType\":{\"query\":\"National\"}}},{\"match\":{\"apprenticeshipLevel\":{\"query\":\"Advanced\"}}}]}}}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #13
0
        public void Search_ShouldSearchNationalApprenticeships()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                ApprenticeshipLevel = "All",
                Keywords            = "baker",
                PageNumber          = 1,
                PageSize            = 5,
                SearchField         = ApprenticeshipSearchField.All,
                SortType            = VacancySearchSortType.ClosingDate,
                VacancyLocationType = VacancyLocationType.National
            };

            const string expectedJsonQuery = "{\"from\":0,\"query\":{\"bool\":{\"must\":[{\"bool\":{\"should\":[{\"match\":{\"title\":{\"boost\":1.5,\"fuzziness\":1,\"minimum_should_match\":\"100%\",\"operator\":\"and\",\"prefix_length\":1,\"query\":\"baker\"}}},{\"match\":{\"description\":{\"boost\":1.0,\"fuzziness\":1,\"minimum_should_match\":\"2<75%\",\"prefix_length\":1,\"query\":\"baker\"}}},{\"match\":{\"employerName\":{\"boost\":5.0,\"fuzziness\":1,\"minimum_should_match\":\"100%\",\"operator\":\"and\",\"prefix_length\":1,\"query\":\"baker\"}}}]}},{\"match\":{\"vacancyLocationType\":{\"query\":\"National\"}}}]}},\"size\":5,\"sort\":[{\"closingDate\":{\"order\":\"asc\"}}],\"track_scores\":true}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #14
0
        public void Search_ShouldSearchByLatAndLongAndSortByDistance()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber          = 1,
                PageSize            = 100,
                VacancyLocationType = VacancyLocationType.NonNational,
                Latitude            = 52.4088862063274,
                Longitude           = 1.50554768088033,
                SearchRadius        = 40.5,
                SortType            = VacancySearchSortType.Distance
            };

            const string expectedJsonQuery = "{\"from\":0,\"query\":{\"bool\":{\"filter\":[{\"geo_distance\":{\"distance\":\"40.5mi\",\"location\":{\"lat\":52.4088862063274,\"lon\":1.50554768088033}}}],\"must\":[{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}}]}},\"size\":100,\"sort\":[{\"_geo_distance\":{\"distance_type\":\"arc\",\"unit\":\"mi\",\"location\":[{\"lat\":52.4088862063274,\"lon\":1.50554768088033}]}},{\"postedDate\":{\"order\":\"desc\"}},{\"vacancyReference\":{\"order\":\"desc\"}}],\"track_scores\":true}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #15
0
        public void Search_ShouldSortByExpectedStartDate()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber          = 1,
                PageSize            = 100,
                VacancyLocationType = VacancyLocationType.NonNational,
                StandardLarsCodes   = new List <string> {
                    "123", "124"
                },
                SortType = VacancySearchSortType.ExpectedStartDate
            };

            const string expectedJsonQuery = "{\"from\":0,\"size\":100,\"track_scores\":true,\"sort\":[{\"startDate\":{\"order\":\"asc\"}},{\"vacancyReference\":{\"order\":\"asc\"}}],\"query\":{\"bool\":{\"must\":[{\"terms\":{\"standardLarsCode\":[\"123\",\"124\"]}},{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}}]}}}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #16
0
        public void Search_ShouldSearchByFrameworkLarsCode()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber          = 1,
                PageSize            = 100,
                VacancyLocationType = VacancyLocationType.NonNational,
                FrameworkLarsCodes  = new List <string> {
                    "502", "501"
                },
                SortType = VacancySearchSortType.RecentlyAdded
            };

            const string expectedJsonQuery = "{\"from\":0,\"query\":{\"bool\":{\"must\":[{\"terms\":{\"frameworkLarsCode\":[\"502\",\"501\"]}},{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}}]}},\"size\":100,\"sort\":[{\"postedDate\":{\"order\":\"desc\"}},{\"vacancyReference\":{\"order\":\"desc\"}}],\"track_scores\":true}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #17
0
        public void Search_ShouldIncludeGeoDistanceInSort()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                ApprenticeshipLevel = "Higher",
                Latitude            = 52.4088862063274,
                Longitude           = 1.50554768088033,
                SearchRadius        = null,
                PageNumber          = 1,
                PageSize            = 5,
                SearchField         = ApprenticeshipSearchField.All,
                SortType            = VacancySearchSortType.ClosingDate,
                VacancyLocationType = VacancyLocationType.NonNational
            };

            const string expectedJsonQuery = "{\"from\":0,\"size\":5,\"track_scores\":true,\"sort\":[{\"closingDate\":{\"order\":\"asc\"}},{\"_geo_distance\":{\"distance_type\":\"arc\",\"unit\":\"mi\",\"location\":[{\"lat\":52.4088862063274,\"lon\":1.50554768088033}]}}],\"query\":{\"bool\":{\"must\":[{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}},{\"match\":{\"apprenticeshipLevel\":{\"query\":\"Higher\"}}}]}}}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #18
0
        private void AssertSearch(ApprenticeshipSearchRequestParameters parameters, string expectedJsonQuery)
        {
            Func <SearchDescriptor <ApprenticeshipSearchResult>, ISearchRequest> actualSearchDescriptorFunc = SetupApprenticeshipClient(parameters);

            var baseSearchDescriptor = new SearchDescriptor <ApprenticeshipSearchResult>();
            var query = actualSearchDescriptorFunc(baseSearchDescriptor);

            var elasticClient = new ElasticClient();
            var stream        = new MemoryStream();

            elasticClient.RequestResponseSerializer.Serialize(query, stream);
            var actualJsonQuery = System.Text.Encoding.UTF8.GetString(stream.ToArray());

            var actualJsonQueryJToken = JToken.Parse(actualJsonQuery);

            var expectedJsonQueryJToken = JToken.Parse(expectedJsonQuery);

            actualJsonQueryJToken.Should().BeEquivalentTo(expectedJsonQueryJToken);
        }
Beispiel #19
0
        public void Search_ShouldSearchByLatAndLong()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                ApprenticeshipLevel = "All",
                Keywords            = "baker",
                Latitude            = 52.4088862063274,
                Longitude           = 1.50554768088033,
                PageNumber          = 1,
                PageSize            = 5,
                SearchField         = ApprenticeshipSearchField.All,
                SearchRadius        = 40,
                SortType            = VacancySearchSortType.Distance,
                VacancyLocationType = VacancyLocationType.NonNational
            };

            const string expectedJsonQuery = "{\"from\":0,\"query\":{\"bool\":{\"filter\":[{\"geo_distance\":{\"distance\":\"40mi\",\"location\":{\"lat\":52.4088862063274,\"lon\":1.50554768088033}}}],\"must\":[{\"bool\":{\"should\":[{\"match\":{\"title\":{\"boost\":1.5,\"fuzziness\":1,\"minimum_should_match\":\"100%\",\"operator\":\"and\",\"prefix_length\":1,\"query\":\"baker\"}}},{\"match\":{\"description\":{\"boost\":1.0,\"fuzziness\":1,\"minimum_should_match\":\"2<75%\",\"prefix_length\":1,\"query\":\"baker\"}}},{\"match\":{\"employerName\":{\"boost\":5.0,\"fuzziness\":1,\"minimum_should_match\":\"100%\",\"operator\":\"and\",\"prefix_length\":1,\"query\":\"baker\"}}}]}},{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}}]}},\"size\":5,\"sort\":[{\"_geo_distance\":{\"distance_type\":\"arc\",\"location\":[{\"lat\":52.4088862063274,\"lon\":1.50554768088033}],\"unit\":\"mi\"}},{\"postedDate\":{\"order\":\"desc\"}},{\"vacancyReference\":{\"order\":\"desc\"}}],\"track_scores\":true}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #20
0
        public void Search_ShouldExcludeSpecifiedVacancies()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                ApprenticeshipLevel = "All",
                CategoryCode        = "SSAT1.00",
                ExcludeVacancyIds   = new[] { 123456, 789012 },
                Latitude            = 52.4088862063274,
                Longitude           = -1.50554768088033,
                PageNumber          = 1,
                PageSize            = 5,
                SearchField         = ApprenticeshipSearchField.All,
                SearchRadius        = 5,
                SortType            = VacancySearchSortType.Distance,
                VacancyLocationType = VacancyLocationType.NonNational
            };

            const string expectedJsonQuery = "{\"from\":0,\"size\":5,\"track_scores\":true,\"sort\":[{\"_geo_distance\":{\"distance_type\":\"arc\",\"unit\":\"mi\",\"location\":[{\"lat\":52.4088862063274,\"lon\":-1.50554768088033}]}},{\"postedDate\":{\"order\":\"desc\"}},{\"vacancyReference\":{\"order\":\"desc\"}}],\"query\":{\"bool\":{\"filter\":[{\"geo_distance\":{\"distance\":\"5mi\",\"location\":{\"lat\":52.4088862063274,\"lon\":-1.50554768088033}}}],\"must\":[{\"terms\":{\"categoryCode\":[\"SSAT1.00\"]}},{\"match\":{\"vacancyLocationType\":{\"query\":\"NonNational\"}}}],\"must_not\":[{\"ids\":{\"values\":[\"123456\",\"789012\"]}}]}}}";

            AssertSearch(parameters, expectedJsonQuery);
        }
Beispiel #21
0
        private QueryContainer GetKeywordQuery(ApprenticeshipSearchRequestParameters parameters, QueryContainerDescriptor <ApprenticeshipSearchResult> q)
        {
            QueryContainer keywordQuery = null;

            if (!string.IsNullOrWhiteSpace(parameters.Keywords) &&
                (parameters.SearchField == ApprenticeshipSearchField.All || parameters.SearchField == ApprenticeshipSearchField.JobTitle))
            {
                var queryClause = q.Match(m =>
                                          BuildFieldQuery(m, _searchFactorConfiguration.JobTitleFactors)
                                          .Field(f => f.Title).Query(parameters.Keywords));

                keywordQuery |= queryClause;
            }

            if (!string.IsNullOrWhiteSpace(parameters.Keywords) &&
                (parameters.SearchField == ApprenticeshipSearchField.All || parameters.SearchField == ApprenticeshipSearchField.Description))
            {
                var queryClause = q.Match(m =>
                                          BuildFieldQuery(m, _searchFactorConfiguration.DescriptionFactors)
                                          .Field(f => f.Description).Query(parameters.Keywords)
                                          );

                keywordQuery |= queryClause;
            }

            if (!string.IsNullOrWhiteSpace(parameters.Keywords) &&
                (parameters.SearchField == ApprenticeshipSearchField.All || parameters.SearchField == ApprenticeshipSearchField.Employer))
            {
                var queryClause = q.Match(m =>
                                          BuildFieldQuery(m, _searchFactorConfiguration.EmployerFactors)
                                          .Field(f => f.EmployerName).Query(parameters.Keywords)
                                          );

                keywordQuery |= queryClause;
            }

            return(keywordQuery);
        }
Beispiel #22
0
        private ApprenticeshipSearchRequestParameters GetSearchClientParameters(VacancySearchParameters parameters)
        {
            var searchClientParameters = new ApprenticeshipSearchRequestParameters
            {
                FrameworkLarsCodes  = parameters.FrameworkLarsCodes,
                StandardLarsCodes   = parameters.StandardLarsCodes,
                PageSize            = parameters.PageSize,
                PageNumber          = parameters.PageNumber,
                FromDate            = parameters.FromDate,
                VacancyLocationType = string.IsNullOrEmpty(parameters.LocationType) ? VacancyLocationType.Unknown : (VacancyLocationType)Enum.Parse(typeof(VacancyLocationType), parameters.LocationType),
                Longitude           = parameters.Longitude,
                Latitude            = parameters.Latitude,
                SearchRadius        = parameters.DistanceInMiles,
                CalculateSubCategoryAggregations = false,
                Ukprn = parameters.Ukprn
            };

            switch (parameters.SortBy)
            {
            case SortBy.Age:
                searchClientParameters.SortType = VacancySearchSortType.RecentlyAdded;
                break;

            case SortBy.ExpectedStartDate:
                searchClientParameters.SortType = VacancySearchSortType.ExpectedStartDate;
                break;

            case SortBy.Distance:
                searchClientParameters.SortType = VacancySearchSortType.Distance;
                break;

            default:
                searchClientParameters.SortType = VacancySearchSortType.Relevancy;
                break;
            }

            return(searchClientParameters);
        }
Beispiel #23
0
        private void SetHitValuesOnSearchResults(ApprenticeshipSearchRequestParameters searchParameters, ISearchResponse <ApprenticeshipSearchResult> results)
        {
            foreach (var result in results.Documents)
            {
                var hitMd = results.Hits.First(h => h.Id == result.Id.ToString(CultureInfo.InvariantCulture));

                if (searchParameters.CanSortByGeoDistance)
                {
                    try
                    {
                        var distance = hitMd.Sorts.ElementAt(GetGeoDistanceSortHitPosition(searchParameters));
                        result.Distance = Convert.ToDouble(distance);
                    }
                    catch (Exception e)
                    {
                        _logger?.Error(e, "Error converting distance sort value from Elastic Result Set");
                        result.Distance = 0;
                    }
                }

                result.Score = hitMd.Score.GetValueOrDefault(0);
            }
        }
Beispiel #24
0
        public void Search_ThrowsException_WhenItReachs_TenThousands_Record()
        {
            var parameters = new ApprenticeshipSearchRequestParameters
            {
                PageNumber          = 101,
                PageSize            = 100,
                VacancyLocationType = VacancyLocationType.NonNational,
                StandardLarsCodes   = new List <string> {
                    "123", "124"
                },
                FrameworkLarsCodes = new List <string> {
                    "502", "501"
                },
                Latitude     = 52.4088862063274,
                Longitude    = 1.50554768088033,
                Ukprn        = 12345678,
                SearchRadius = 40,
                FromDate     = DateTime.Parse("2018-11-24"),
                SortType     = VacancySearchSortType.ExpectedStartDate
            };

            AssertException(parameters);
        }
Beispiel #25
0
        internal static SortDescriptor <ApprenticeshipSearchResult> TrySortByGeoDistance(this SortDescriptor <ApprenticeshipSearchResult> sortDescriptor, ApprenticeshipSearchRequestParameters searchParameters)
        {
            if (searchParameters.CanSortByGeoDistance)
            {
                sortDescriptor.GeoDistance(g => g
                                           .Field(f => f.Location)
                                           .DistanceType(GeoDistanceType.Arc)
                                           .Unit(DistanceUnit.Miles)
                                           .Points(new GeoLocation(searchParameters.Latitude.Value, searchParameters.Longitude.Value)));
            }

            return(sortDescriptor);
        }
Beispiel #26
0
        private QueryContainer GetQuery(ApprenticeshipSearchRequestParameters parameters, QueryContainerDescriptor <ApprenticeshipSearchResult> q)
        {
            if (!string.IsNullOrEmpty(parameters.VacancyReference))
            {
                return(q.Bool(fq =>
                              fq.Filter(f =>
                                        f.Term(t =>
                                               t.VacancyReference, parameters.VacancyReference))));
            }

            QueryContainer query = null;

            query &= GetKeywordQuery(parameters, q);

            if (parameters.FrameworkLarsCodes.Any() || parameters.StandardLarsCodes.Any())
            {
                var queryClause = q.Terms(apprenticeship => apprenticeship.Field(f => f.FrameworkLarsCode).Terms(parameters.FrameworkLarsCodes)) ||
                                  q.Terms(apprenticeship => apprenticeship.Field(f => f.StandardLarsCode).Terms(parameters.StandardLarsCodes));

                query &= queryClause;
            }

            if (!string.IsNullOrWhiteSpace(parameters.CategoryCode))
            {
                var categoryCodes = new List <string>
                {
                    parameters.CategoryCode
                };

                var queryCategory = q.Terms(f => f.Field(g => g.CategoryCode).Terms(categoryCodes.Distinct()));

                query &= queryCategory;
            }

            if (parameters.ExcludeVacancyIds != null && parameters.ExcludeVacancyIds.Any())
            {
                var queryExcludeVacancyIds = !q.Ids(i => i.Values(parameters.ExcludeVacancyIds.Select(x => x.ToString(CultureInfo.InvariantCulture))));
                query &= queryExcludeVacancyIds;
            }

            if (parameters.VacancyLocationType != VacancyLocationType.Unknown)
            {
                var queryVacancyLocation = q.Match(m => m.Field(f => f.VacancyLocationType).Query(parameters.VacancyLocationType.ToString()));

                query &= queryVacancyLocation;
            }

            if (parameters.FromDate.HasValue)
            {
                var queryClause = q.DateRange(range =>
                                              range.Field(apprenticeship => apprenticeship.PostedDate)
                                              .GreaterThanOrEquals(parameters.FromDate));

                query &= queryClause;
            }

            if (parameters.Ukprn.HasValue)
            {
                var queryClause = q
                                  .Match(m => m.Field(f => f.Ukprn)
                                         .Query(parameters.Ukprn.ToString()));
                query &= queryClause;
            }

            if (!string.IsNullOrWhiteSpace(parameters.ApprenticeshipLevel) && parameters.ApprenticeshipLevel != "All")
            {
                var queryClause = q
                                  .Match(m => m.Field(f => f.ApprenticeshipLevel)
                                         .Query(parameters.ApprenticeshipLevel));
                query &= queryClause;
            }

            if (parameters.DisabilityConfidentOnly)
            {
                // Nest package won't allow a boolean directly and has to be a string
                // Elastic will throw if its not lower case
                // As we specifically only add this when this statement is true, explicit value is passed.
                var queryDisabilityConfidentOnly = q
                                                   .Match(m => m.Field(f => f.IsDisabilityConfident)
                                                          .Query("true"));

                query &= queryDisabilityConfidentOnly;
            }

            if (parameters.CanFilterByGeoDistance)
            {
                var geoQueryClause = q.Bool(qf => qf.Filter(f => f
                                                            .GeoDistance(vs => vs
                                                                         .Field(field => field.Location)
                                                                         .Location(parameters.Latitude.Value, parameters.Longitude.Value)
                                                                         .Distance(parameters.SearchRadius.Value, DistanceUnit.Miles))));

                query &= geoQueryClause;
            }

            return(query);
        }
Beispiel #27
0
        private static void SetSort(SearchDescriptor <ApprenticeshipSearchResult> search, ApprenticeshipSearchRequestParameters parameters)
        {
            switch (parameters.SortType)
            {
            case VacancySearchSortType.RecentlyAdded:
                search.Sort(r => r
                            .Descending(s => s.PostedDate)
                            .TrySortByGeoDistance(parameters)
                            .Descending(s => s.VacancyReference));
                break;

            case VacancySearchSortType.Distance:
                search.Sort(s => s
                            .TrySortByGeoDistance(parameters)
                            .Descending(r => r.PostedDate)
                            .Descending(r => r.VacancyReference));
                break;

            case VacancySearchSortType.ClosingDate:
                search.Sort(s => s
                            .Ascending(r => r.ClosingDate)
                            .TrySortByGeoDistance(parameters));
                break;

            case VacancySearchSortType.ExpectedStartDate:
                search.Sort(s => s
                            .Ascending(r => r.StartDate)
                            .Ascending(r => r.VacancyReference)
                            .TrySortByGeoDistance(parameters));
                break;

            default:
                search.Sort(s => s
                            .Descending(SortSpecialField.Score)
                            .TrySortByGeoDistance(parameters));
                break;
            }
        }
Beispiel #28
0
        private static Func <SearchDescriptor <ApprenticeshipSearchResult>, ISearchRequest> SetupApprenticeshipClient(ApprenticeshipSearchRequestParameters parameters)
        {
            var searchResponse = new Mock <ISearchResponse <ApprenticeshipSearchResult> >();

            searchResponse.Setup(s => s.Total).Returns(0);
            searchResponse.Setup(s => s.Documents).Returns(Enumerable.Empty <ApprenticeshipSearchResult>().ToList());

            Func <SearchDescriptor <ApprenticeshipSearchResult>, ISearchRequest> actualSearchDescriptorFunc = null;

            var mockClient = new Mock <IElasticClient>();

            mockClient.Setup(c => c.Search <ApprenticeshipSearchResult>(It.IsAny <Func <SearchDescriptor <ApprenticeshipSearchResult>, ISearchRequest> >()))
            .Callback <Func <SearchDescriptor <ApprenticeshipSearchResult>, ISearchRequest> >(a => actualSearchDescriptorFunc = a)
            .Returns(searchResponse.Object);

            var mockFactory = new Mock <IElasticClientFactory>();

            mockFactory.Setup(f => f.CreateClient(It.IsAny <Action <IApiCallDetails> >())).Returns(mockClient.Object);

            var mockLogger = new Mock <ILog>();

            var sut = new ApprenticeshipSearchClient(mockFactory.Object, "apprenticeships", mockLogger.Object);

            var response = sut.Search(parameters);

            return(actualSearchDescriptorFunc);
        }
Beispiel #29
0
 private void AssertException(ApprenticeshipSearchRequestParameters parameters)
 {
     Assert.Throws <InvalidOperationException>(() => SetupApprenticeshipClient(parameters));
 }