private static IReadOnlyCollection <SearchResultFacet> GetFacets( WebsiteSearchQuery query, SearchResult result, IEnumerable <DocumentField> allFields) { if (query.Facets == null || !query.Facets.Any()) { return(Array.Empty <SearchResultFacet>()); } var facetFields = IgnoreDuplicates( allFields .Where(f => f.FacetedSearchEnabled && f.Label != null), f => f.Name).ToDictionary(f => f.Name); // Returning exactly the requested fasets if no documents were found. if (result.TotalHits == 0) { return((from facet in query.Facets let facetField = facetFields[facet.Name] let previewFunc = facetField.Facet.PreviewFunction ?? (value => value?.ToString()) select new SearchResultFacet { Name = facet.Name, Hits = facet.Selections .Select(value => new SearchResultFacetHit { Value = value, Label = previewFunc(value), HitCount = 0 }) .ToArray() }).ToArray()); } return((from facet in result.Facets let facetField = facetFields[facet.Key] let previeFunc = facetField.Facet.PreviewFunction ?? (value => value?.ToString()) select new SearchResultFacet { Name = facet.Key, Hits = facet.Value .Select(v => new SearchResultFacetHit { Value = v.Value, Label = previeFunc(v.Value), HitCount = v.HitCount }) .ToArray() }).ToArray()); }
public static WebsiteSearchResult Search(WebsiteSearchQuery query) { Verify.ArgumentNotNull(query, nameof(query)); // If there's only one website, no need to check whether the results belong to current site only if (query.CurrentSiteOnly && NotMoreThanOneSitePresent(query.Culture)) { query.CurrentSiteOnly = false; } if (SearchFacade.SearchEnabled) { return(SearchUsingSearchProvider(query)); } return(SimpleSearch(query)); }
internal static WebsiteSearchResult SimpleSearch(WebsiteSearchQuery query) { var keywords = query.Keywords; keywords = keywords.Distinct().OrderByDescending(keyword => keyword.Length).Take(MaximumTermCount).ToArray(); var allResults = SearchPages(keywords, query.CurrentSiteOnly) .Concat(SearchInData(keywords, query.CurrentSiteOnly)) .Take(ResultsMaxLength).ToList(); return(new WebsiteSearchResult { Entries = allResults .Skip(query.PageSize * query.PageNumber) .Take(query.PageSize).ToList(), ResultsFound = allResults.Count }); }
private static WebsiteSearchResult SearchUsingSearchProvider(WebsiteSearchQuery query) { string text = string.Join(" ", query.Keywords); var searchQuery = new SearchQuery(text, query.Culture) { MaxDocumentsNumber = query.PageSize, SearchResultOffset = query.PageSize * query.PageNumber, SortOptions = query.SortOptions, HighlightSettings = { Enabled = true, FragmentsCount = 1, FragmentSize = 120 } }; var allFields = SearchFacade.DocumentSources.SelectMany(ds => ds.CustomFields).ToList(); foreach (var facet in query.Facets ?? Enumerable.Empty <WebsiteSearchQueryFacet>()) { // TODO: use an overload for SearchQuery.AddFieldFacet(...) once C1 6.2 is out searchQuery.AddFieldFacet(facet.Name); var field = allFields.Where(f => f.Facet != null).FirstOrDefault(f => f.Name == facet.Name); if (facet.Selections != null && facet.Selections.Length > 0) { searchQuery.Selection.Add(new SearchQuerySelection { FieldName = facet.Name, Values = facet.Selections, Operation = field.Facet.FacetType == FacetType.SingleValue ? SearchQuerySelectionOperation.Or : SearchQuerySelectionOperation.And }); } } searchQuery.ShowOnlyDocumentsWithUrls(); var filterByAncestors = new List <EntityToken>(); if (query.CurrentSiteOnly) { filterByAncestors.Add(GetRootPageEntityToken()); } if (query.FilterByAncestorEntityTokens?.Any() ?? false) { filterByAncestors.AddRange(query.FilterByAncestorEntityTokens); } if (filterByAncestors.Any()) { searchQuery.FilterByAncestors(filterByAncestors.ToArray()); } if (query.DataTypes != null && query.DataTypes.Length > 0) { searchQuery.FilterByDataTypes(query.DataTypes); } if (query.PageTypes != null && query.PageTypes.Length > 0) { searchQuery.Selection.Add(new SearchQuerySelection { FieldName = PageTypeIdFieldName, Operation = SearchQuerySelectionOperation.Or, Values = query.PageTypes }); } var result = SearchFacade.SearchProvider.SearchAsync(searchQuery).Result; if (result == null) { return(new WebsiteSearchResult()); } return(new WebsiteSearchResult { Entries = result.Items.Select(ToSearchResultEntry).ToList(), Facets = GetFacets(query, result, allFields), ResultsFound = result.TotalHits }); }