private IEnumerable <NavigationNode> GetNavigationNodesBySearch(SPWeb web, NavigationSearchSettings settings, IEnumerable <string> additionalFilters = null) { var filters = new List <string>(settings.GlobalFilters); // Check if find result source var searchResultSource = this.searchHelper.GetResultSourceByName(web.Site, settings.ResultSourceName, SearchObjectLevel.Ssa); if (searchResultSource == null) { this.logger.Error("searchResultSource is null in GSoft.Dynamite.Navigation.NavigationService.GetNavigationNodeItems"); return(new List <NavigationNode>()); } var query = new KeywordQuery(web) { SourceId = searchResultSource.Id, TrimDuplicates = false, RowLimit = 500 }; // Add defined filters if (additionalFilters != null) { filters.AddRange(additionalFilters); } if (settings.SelectedProperties != null && settings.SelectedProperties.Any()) { query.SelectProperties.AddRange(settings.SelectedProperties.ToArray()); } // TODO: For now, the filters are applied seperated by whitespaces which means "AND" in KQL land. // TODO: We should figure out a way to make this more flexible to use "OR" if necessary. query.QueryText = string.Join(" ", filters.Where(filter => !string.IsNullOrEmpty(filter))); // Execute search query var tables = new SearchExecutor().ExecuteQuery(query); if (tables.Exists(KnownTableTypes.RelevantResults)) { // Build navigation nodes for search results var results = tables.Filter("TableType", KnownTableTypes.RelevantResults).Single(relevantTable => relevantTable.QueryRuleId == Guid.Empty); var nodes = results.Table.Rows.Cast <DataRow>().Select(dataRow => new NavigationNode(dataRow, settings.NavigationManagedPropertyName)); this.logger.Info( "GetNavigationNodeItems: Found {0} items with search query '{1}' from source '{2}'.", results.Table.Rows.Count, query.QueryText, settings.ResultSourceName); return(nodes); } this.logger.Error( "GetNavigationNodeItems: No relevant results table found with search query '{0}' from source '{1}'.", query.QueryText, settings.ResultSourceName); return(new List <NavigationNode>()); }
/// <summary> /// Get the peer url for a page represents a cross site publishing catalog item /// </summary> /// <param name="currentUrl">The current page url</param> /// <param name="label">The target label to resolve</param> /// <param name="associationKeyManagedPropertyName">The content association key search managed property name</param> /// <param name="associationKeyValue">The value of the content association key for the current item</param> /// <param name="languageManagedPropertyName">The language search managed property name</param> /// <param name="catalogNavigationTermManagedPropertyName">The navigation search managed property name used for the friendly url generation</param> /// <returns>The url of the peer page</returns> public Uri GetPeerCatalogItemUrl( Uri currentUrl, VariationLabelInfo label, string associationKeyManagedPropertyName, string associationKeyValue, string languageManagedPropertyName, string catalogNavigationTermManagedPropertyName) { ValidateProperties("GetPeerCatalogItemUrl", associationKeyManagedPropertyName, associationKeyValue, catalogNavigationTermManagedPropertyName); var url = new Uri(Variations.GetPeerUrl(SPContext.Current.Web, currentUrl.AbsoluteUri, label.Title), UriKind.Relative); var searchResultSource = this.searchHelper.GetResultSourceByName(SPContext.Current.Site, LocalSharePointResultsSourceName, SearchObjectLevel.Ssa); // We take the Title of the Label because the Label.Language is always a language from a language pack (supported). Sometimes, we deal with Not implemented language (ie Inuktitut "IU"). // Our workaround is to set the Title as the agnostic language label ("en", "fr", "iu", etc). // For backward compatibility purpose, we will test the length of the Title. If it's not 2, we will fallback on the Language of the Label. // This is not 100% robust but it the only way we found to deal with unsupported language. var labelLocaleAgnosticLanguage = label.Title.Length == 2 ? label.Title : label.Language.Split('-').FirstOrDefault(); var queryText = string.Format( CultureInfo.InvariantCulture, "{0}:{1} {2}={3}", associationKeyManagedPropertyName, associationKeyValue, languageManagedPropertyName, labelLocaleAgnosticLanguage); var query = new KeywordQuery(SPContext.Current.Web) { SourceId = searchResultSource.Id, QueryText = queryText }; // Search query must include the following properties for the friendly URL to work query.SelectProperties.AddRange(new[] { catalogNavigationTermManagedPropertyName, BuiltInManagedProperties.Url, BuiltInManagedProperties.SiteUrl, BuiltInManagedProperties.ListId }); var tables = new SearchExecutor().ExecuteQuery(query); if (tables.Exists(KnownTableTypes.RelevantResults)) { var table = tables.Filter("TableType", KnownTableTypes.RelevantResults).Single(relevantTable => relevantTable.QueryRuleId == Guid.Empty); if (table != null && table.ResultRows.Count == 1 && table.Table.Columns.Contains(BuiltInManagedProperties.Url)) { url = new Uri(table.Table.Rows[0][BuiltInManagedProperties.Url].ToString()); } } return(url); }
/// <summary> /// Get the peer url for a page represents a cross site publishing catalog item /// </summary> /// <param name="currentUrl">The current page url</param> /// <param name="label">The target label to resolve</param> /// <param name="associationKeyManagedPropertyName">The content association key search managed property name</param> /// <param name="associationKeyValue">The value of the content association key for the current item</param> /// <param name="languageManagedPropertyName">The language search managed property name</param> /// <param name="catalogNavigationTermManagedPropertyName">The navigation search managed property name used for the friendly url generation</param> /// <returns>The url of the peer page</returns> public Uri GetPeerCatalogItemUrl( Uri currentUrl, VariationLabelInfo label, string associationKeyManagedPropertyName, string associationKeyValue, string languageManagedPropertyName, string catalogNavigationTermManagedPropertyName) { ValidateProperties("GetPeerCatalogItemUrl", associationKeyManagedPropertyName, associationKeyValue, catalogNavigationTermManagedPropertyName); var url = new Uri(Variations.GetPeerUrl(SPContext.Current.Web, currentUrl.AbsolutePath, label.Title), UriKind.Relative); var searchResultSource = this.searchHelper.GetResultSourceByName(SPContext.Current.Site, LocalSharePointResultsSourceName, SearchObjectLevel.Ssa); var queryText = string.Format( CultureInfo.InvariantCulture, "{0}:{1} {2}:{3}", associationKeyManagedPropertyName, associationKeyValue, languageManagedPropertyName, label.Locale); var query = new KeywordQuery(SPContext.Current.Web) { SourceId = searchResultSource.Id, QueryText = queryText }; // Search query must include the following properties for the friendly URL to work query.SelectProperties.AddRange(new[] { catalogNavigationTermManagedPropertyName, BuiltInManagedProperties.Url.Name, BuiltInManagedProperties.SiteUrl.Name, BuiltInManagedProperties.ListId.Name }); var tables = new SearchExecutor().ExecuteQuery(query); if (tables.Exists(KnownTableTypes.RelevantResults)) { var table = tables.Filter("TableType", KnownTableTypes.RelevantResults).Single(relevantTable => relevantTable.QueryRuleId == Guid.Empty); if (table != null && table.ResultRows.Count == 1 && table.Table.Columns.Contains(BuiltInManagedProperties.Url.Name)) { url = new Uri(table.Table.Rows[0][BuiltInManagedProperties.Url.Name].ToString(), UriKind.Absolute); // Convert the absolute Uri into a relative Uri. This is required for environments using a load balancer, // because we need to ignore the load balancer's port found in the absolute Uri. url = new Uri(url.AbsolutePath, UriKind.Relative); } } return(url); }
private IEnumerable<NavigationNode> GetNavigationNodesBySearch(SPWeb web, NavigationSearchSettings settings, IEnumerable<string> additionalFilters = null) { var filters = new List<string>(settings.GlobalFilters); // Check if find result source var searchResultSource = this.searchHelper.GetResultSourceByName(web.Site, settings.ResultSourceName, SearchObjectLevel.Ssa); if (searchResultSource == null) { this.logger.Error("searchResultSource is null in GSoft.Dynamite.Navigation.NavigationService.GetNavigationNodeItems"); return new List<NavigationNode>(); } var query = new KeywordQuery(web) { SourceId = searchResultSource.Id, TrimDuplicates = false, RowLimit = 500 }; // Add defined filters if (additionalFilters != null) { filters.AddRange(additionalFilters); } if (settings.SelectedProperties != null && settings.SelectedProperties.Any()) { query.SelectProperties.AddRange(settings.SelectedProperties.ToArray()); } // TODO: For now, the filters are applied seperated by whitespaces which means "AND" in KQL land. // TODO: We should figure out a way to make this more flexible to use "OR" if necessary. query.QueryText = string.Join(" ", filters.Where(filter => !string.IsNullOrEmpty(filter))); // Execute search query var tables = new SearchExecutor().ExecuteQuery(query); if (tables.Exists(KnownTableTypes.RelevantResults)) { // Build navigation nodes for search results var results = tables.Filter("TableType", KnownTableTypes.RelevantResults).Single(relevantTable => relevantTable.QueryRuleId == Guid.Empty); var nodes = results.Table.Rows.Cast<DataRow>().Select(dataRow => new NavigationNode(dataRow, settings.NavigationManagedPropertyName)); this.logger.Info( "GetNavigationNodeItems: Found {0} items with search query '{1}' from source '{2}'.", results.Table.Rows.Count, query.QueryText, settings.ResultSourceName); return nodes; } this.logger.Error( "GetNavigationNodeItems: No relevant results table found with search query '{0}' from source '{1}'.", query.QueryText, settings.ResultSourceName); return new List<NavigationNode>(); }
/// <summary> /// Get the peer url for a page represents a cross site publishing catalog item /// </summary> /// <param name="currentUrl">The current page url</param> /// <param name="label">The target label to resolve</param> /// <param name="associationKeyManagedPropertyName">The content association key search managed property name</param> /// <param name="associationKeyValue">The value of the content association key for the current item</param> /// <param name="languageManagedPropertyName">The language search managed property name</param> /// <param name="catalogNavigationTermManagedPropertyName">The navigation search managed property name used for the friendly url generation</param> /// <returns>The url of the peer page</returns> public Uri GetPeerCatalogItemUrl( Uri currentUrl, VariationLabelInfo label, string associationKeyManagedPropertyName, string associationKeyValue, string languageManagedPropertyName, string catalogNavigationTermManagedPropertyName) { ValidateProperties("GetPeerCatalogItemUrl", associationKeyManagedPropertyName, associationKeyValue, catalogNavigationTermManagedPropertyName); var url = new Uri(Variations.GetPeerUrl(SPContext.Current.Web, currentUrl.AbsolutePath, label.Title), UriKind.Relative); var searchResultSource = this.searchHelper.GetResultSourceByName(SPContext.Current.Site, LocalSharePointResultsSourceName, SearchObjectLevel.Ssa); var queryText = string.Format( CultureInfo.InvariantCulture, "{0}:{1} {2}:{3}", associationKeyManagedPropertyName, associationKeyValue, languageManagedPropertyName, label.Language); var query = new KeywordQuery(SPContext.Current.Web) { SourceId = searchResultSource.Id, QueryText = queryText }; // Search query must include the following properties for the friendly URL to work query.SelectProperties.AddRange(new[] { catalogNavigationTermManagedPropertyName, BuiltInManagedProperties.Url.Name, BuiltInManagedProperties.SiteUrl.Name, BuiltInManagedProperties.ListId.Name }); var tables = new SearchExecutor().ExecuteQuery(query); if (tables.Exists(KnownTableTypes.RelevantResults)) { var table = tables.Filter("TableType", KnownTableTypes.RelevantResults).Single(relevantTable => relevantTable.QueryRuleId == Guid.Empty); if (table != null && table.ResultRows.Count == 1 && table.Table.Columns.Contains(BuiltInManagedProperties.Url.Name)) { url = new Uri(table.Table.Rows[0][BuiltInManagedProperties.Url.Name].ToString(), UriKind.Absolute); // Convert the absolute Uri into a relative Uri. This is required for environments using a load balancer, // because we need to ignore the load balancer's port found in the absolute Uri. url = new Uri(url.AbsolutePath, UriKind.Relative); } } return url; }
/// <summary> /// Get the peer url for a page represents a cross site publishing catalog item /// </summary> /// <param name="currentUrl">The current page url</param> /// <param name="label">The target label to resolve</param> /// <param name="associationKeyManagedPropertyName">The content association key search managed property name</param> /// <param name="associationKeyValue">The value of the content association key for the current item</param> /// <param name="languageManagedPropertyName">The language search managed property name</param> /// <param name="catalogNavigationTermManagedPropertyName">The navigation search managed property name used for the friendly url generation</param> /// <returns>The url of the peer page</returns> public Uri GetPeerCatalogItemUrl( Uri currentUrl, VariationLabelInfo label, string associationKeyManagedPropertyName, string associationKeyValue, string languageManagedPropertyName, string catalogNavigationTermManagedPropertyName) { ValidateProperties("GetPeerCatalogItemUrl", associationKeyManagedPropertyName, associationKeyValue, catalogNavigationTermManagedPropertyName); var url = new Uri(Variations.GetPeerUrl(SPContext.Current.Web, currentUrl.AbsoluteUri, label.Title), UriKind.Relative); var searchResultSource = this.searchHelper.GetResultSourceByName(SPContext.Current.Site, LocalSharePointResultsSourceName, SearchObjectLevel.Ssa); // We take the Title of the Label because the Label.Language is always a language from a language pack (supported). Sometimes, we deal with Not implemented language (ie Inuktitut "IU"). // Our workaround is to set the Title as the agnostic language label ("en", "fr", "iu", etc). // For backward compatibility purpose, we will test the length of the Title. If it's not 2, we will fallback on the Language of the Label. // This is not 100% robust but it the only way we found to deal with unsupported language. var labelLocaleAgnosticLanguage = label.Title.Length == 2 ? label.Title : label.Language.Split('-').FirstOrDefault(); var queryText = string.Format( CultureInfo.InvariantCulture, "{0}:{1} {2}={3}", associationKeyManagedPropertyName, associationKeyValue, languageManagedPropertyName, labelLocaleAgnosticLanguage); var query = new KeywordQuery(SPContext.Current.Web) { SourceId = searchResultSource.Id, QueryText = queryText }; // Search query must include the following properties for the friendly URL to work query.SelectProperties.AddRange(new[] { catalogNavigationTermManagedPropertyName, BuiltInManagedProperties.Url, BuiltInManagedProperties.SiteUrl, BuiltInManagedProperties.ListId }); var tables = new SearchExecutor().ExecuteQuery(query); if (tables.Exists(KnownTableTypes.RelevantResults)) { var table = tables.Filter("TableType", KnownTableTypes.RelevantResults).Single(relevantTable => relevantTable.QueryRuleId == Guid.Empty); if (table != null && table.ResultRows.Count == 1 && table.Table.Columns.Contains(BuiltInManagedProperties.Url)) { url = new Uri(table.Table.Rows[0][BuiltInManagedProperties.Url].ToString()); } } return url; }