Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 6
0
        /// <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;
        }