/// <summary> /// Filter on rating /// </summary> /// <param name="search"></param> /// <param name="query"></param> /// <returns></returns> private ITypeSearch<Hotel> GetRatingFilter(ITypeSearch<Hotel> search, SearchQuery query) { if (query.RatingFilter > 0) { search = search.Filter(x => x.StarRating.Match(query.RatingFilter)); } return search; }
/// <summary> /// Is city filter active /// </summary> /// <param name="query"></param> /// <returns></returns> private bool IsCityFilterActive(SearchQuery query) { var cities = _popularCitiesService.GetCities(); var city = cities.FirstOrDefault(c => c.Title.Equals(query.Query, StringComparison.InvariantCultureIgnoreCase)); return city != null; }
/// <summary> /// Get order by /// </summary> /// <param name="search"></param> /// <param name="query"></param> /// <returns></returns> private ITypeSearch<Hotel> GetOrderBy(ITypeSearch<Hotel> search, SearchQuery query) { switch (query.SortBy) { case "price": return search.OrderBy(h => h.PriceUSD); case "ratings": return search.OrderByDescending(h => h.StarRating); case "Popularity": return search.OrderByDescending(h => h.StarRating); default: return search.OrderByDescending(h => h.PriceUSD); } }
/// <summary> /// Filter on price /// </summary> /// <param name="search"></param> /// <param name="query"></param> /// <returns></returns> private ITypeSearch<Hotel> GetPriceFilter(ITypeSearch<Hotel> search, SearchQuery query) { if (query.PriceTo > 0) { search = search.Filter(x => x.PriceUSD.InRange((int)query.PriceFrom, (int)query.PriceTo)); } return search; }
/// <summary> /// Get filters /// </summary> /// <param name="search"></param> /// <param name="query"></param> /// <returns></returns> private ITypeSearch<Hotel> GetFilters(ITypeSearch<Hotel> search, SearchQuery query) { search = GetPriceFilter(search, query); search = GetRatingFilter(search, query); search = GetFacilityFilter(search, query); search = GetCityFilter(search, query); return search; }
/// <summary> /// Use this to filter on the Features list. This Filter use the Match method for the filtering for each selected facility /// </summary> /// <param name="search"></param> /// <param name="query"></param> /// <returns></returns> private ITypeSearch<Hotel> GetFacilityFilter(ITypeSearch<Hotel> search, SearchQuery query) { if (query.FacilityFilter != null) { foreach (var item in query.FacilityFilter) { var facility = _facilityService.GetById(item); if (facility != null) { search = search.Filter(x => x.Features.Match(facility.Value)); } } } return search; }
/// <summary> /// Use this to filter for only specific cities. Unfortunately there isn't a city property available. So when searching /// for hotels in particular city Geo search is used. For this example site a range of 20 kilometer is used. /// </summary> /// <param name="search"></param> /// <param name="query"></param> /// <returns></returns> private ITypeSearch<Hotel> GetCityFilter(ITypeSearch<Hotel> search, SearchQuery query) { var cities =_popularCitiesService.GetCities(); var city = cities.FirstOrDefault(c => c.Title.Equals(query.Query, StringComparison.InvariantCultureIgnoreCase)); if (city != null) { search = search.Filter(h => h.GeoCoordinates.WithinDistanceFrom( new GeoLocation(city.Coordinates.Latitude, city.Coordinates.Longitude), 20.Kilometers())); } return search; }
/// <summary> /// Search autocomplete /// First filter the LocationsString after that return the item from the Location array /// We would like to search on country, city etc. /// </summary> /// <param name="query"></param> /// <returns></returns> public IEnumerable<SearchResultItem> SearchAutoComplete(SearchQuery query) { if (string.IsNullOrEmpty(query.Query)) { return Enumerable.Empty<SearchResultItem>(); } var search = _client.Search<Hotel>().Filter(x => x.LocationsString.AnyWordBeginsWith(query.Query)); var results = search.GetResult() .Select(h => h.Locations.FirstOrDefault(x => x.IndexOf(query.Query, StringComparison.InvariantCultureIgnoreCase) != -1)) .Distinct() .Take(_maxAutocompleteResults); return results.Select(q => new SearchResultItem { Title = q }); }
/// <summary> /// Search and filter on price, facilities, rating and city when selected. /// Default order by price /// Use paging functionality for the infinite scroll /// </summary> /// <param name="query"></param> /// <returns></returns> public SearchResult Search(SearchQuery query) { var search = _client.Search<Hotel>(); if (!IsCityFilterActive(query)) // If city filter is active don't perform a search { search = search.For(query.Query); } search = GetFilters(search, query); search = GetOrderBy(search, query); var page = query.CurrentPage == 0 ? 1 : query.CurrentPage; var result = search.Take(_pageSize).Skip((page - 1) * 10).GetResult(); var searchResult = new SearchResult(); searchResult.TotalResults = result.TotalMatching; var totalPages = result.TotalMatching / _pageSize; if (result.TotalMatching % _pageSize > 0) { totalPages++; } searchResult.CurrentPage = page; searchResult.TotalPages = totalPages; searchResult.Results = result.Select(_searchResultItemBuilder.FromHotel); return searchResult; }