More in this section

Search

6 posts, 0 answered
  1. Annie
    Annie avatar
    123 posts
    Registered:
    08 Apr 2009
    09 Jun 2009
    Link to this post
    Hi,

    Whenever we search for something, using the Sitefinity search Blogs are ranked higher than other pages..how do we fix this problem?

    Regards,
    Annie

  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    10 Jun 2009
    Link to this post
    Hello Annie,

    It is possible, but the task is complicated.

    1. You should create a custom search results class that inherits from SearchResults

    Sample code (for illustration)

    namespace Telerik.Search.WebControls 
     
        /// <summary> 
        /// Summary description for CustomSearchResult 
        /// </summary> 
        public class CustomSearchResult : SearchResult 
        { 
            public CustomSearchResult() 
            { 
            } 
            private static string ResolveUrl(string p) 
            { 
                if (p.StartsWith("/")) 
                {   // this is fix for the external pages when page is located in the same site(ex. /Files/Sample.htm) 
                    return p; 
                } 
                CultureInfo culture = null
                string url = UnresolveIndexPath(p, out culture); 
     
                IUrlService langSvc = UrlServices.GetService("LanguageService"); 
     
                if (langSvc != null
                    return langSvc.ResolveLanguageUrl(UrlPath.ResolveUrl(url), culture); 
                return UrlPath.ResolveUrl(url); 
            } 
     
            public IList<ResultItem> Search(string searchQuery, string indexName, int startIndex, int max, string mode, bool escapeChars, out int totalItems) 
            { 
     
                IList<ResultItem> result = new List<ResultItem>(); 
                string[] fields = GetFields(indexName); 
                string indexDirectory = PathUtil.GetIndexPhysicalPath(indexName); 
                IndexSearcher searcher = new IndexSearcher(indexDirectory); 
     
                QueryParser.Operator searchMode = QueryParser.AND_OPERATOR; 
     
                MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer()); 
     
                if (!String.IsNullOrEmpty(mode) 
                    && mode == "AnyWord"
                { 
                    searchMode = QueryParser.OR_OPERATOR; 
                } 
                parser.SetDefaultOperator(searchMode); 
     
                if (escapeChars) 
                { 
                    searchQuery = QueryParser.Escape(searchQuery); 
                } 
     
                Query query = searcher.Rewrite(parser.Parse(searchQuery)); 
                Highlighter highlighter = new Highlighter(new QueryScorer(query)); 
                Hits hits = searcher.Search(query, Sort.INDEXORDER); 
     
                totalItems = hits.Length(); 
                if (max == 0) 
                    max = totalItems; 
                else if (startIndex + max > totalItems) 
                    max = totalItems; 
                else 
                    max = startIndex + max; 
     
                for (int i = startIndex; i < max; i++) 
                { 
                    Document doc = hits.Doc(i); 
                    ResultItem item = new ResultItem(); 
                    item.Title = doc.Get("title"); 
                    item.Url = ResolveUrl(doc.Get("path")); 
                    item.Score = hits.Score(i); 
     
                    StringBuilder snippet = new StringBuilder(); 
                    bool lastAppendedIsSeparator = false
                    for (int k = 0; k < fields.Length; k++) 
                    { 
                        string field = fields[k]; 
                        switch (field.ToLower()) 
                        { 
                            case "title"
                            case "path"
                            case "keywords"
                            case "description"
                                continue
                        } 
                        string[] values = doc.GetValues(field); 
                        if (values != null && values.Length > 0) 
                        { 
                            for (int j = 0; j < values.Length; j++) 
                            { 
                                if (values[j].Length > 0) 
                                { 
                                    snippet.Append(values[j]); 
                                    lastAppendedIsSeparator = false
                                    if (j < values.Length - 1) 
                                    { 
                                        snippet.AppendLine(SearchManager.SEARCH_RESULTS_SEPARATOR); 
                                        lastAppendedIsSeparator = true
                                    } 
                                } 
                            } 
                        } 
                        if (k < fields.Length - 1 && !lastAppendedIsSeparator) 
                        { 
                            snippet.AppendLine(SearchManager.SEARCH_RESULTS_SEPARATOR); 
                            lastAppendedIsSeparator = true
                        } 
                    } 
                    string[] bestFragments = highlighter.GetBestFragments(new StandardAnalyzer(), fields[0], snippet.ToString(), 5); 
                    item.Snippet = String.Join(SearchManager.SEARCH_RESULTS_SEPARATOR, bestFragments); 
                    item.Snippet.TrimEnd(' ', '.'); 
                    item.Snippet += SearchManager.SEARCH_RESULTS_SEPARATOR; 
                    result.Add(item); 
                } 
                searcher.Close(); 
                return result; 
            } 
     
            private static Dictionary<stringstring[]> idxFlds = new Dictionary<stringstring[]>(); 
     
            private static Regex CulterRegex = new Regex(@"^{(\S+)}(.*)", RegexOptions.Compiled); 
     
            private static string UnresolveIndexPath(string path, out CultureInfo culture) 
            { 
                Match match = CulterRegex.Match(path); 
                if (match.Success) 
                { 
                    culture = CultureInfo.GetCultureInfo(match.Groups[1].Value); 
                    return match.Groups[2].Value; 
                } 
                culture = CultureInfo.InvariantCulture; 
                return path; 
            } 
     
            private static string[] GetFields(string provider) 
            { 
                string[] arr; 
                if (!idxFlds.TryGetValue(provider, out arr)) 
                { 
                    List<string> list = new List<string>(); 
                    foreach (IndexingTypeElement element in ConfigHelper.Handler.Indexers) 
                    { 
                        BaseIndexer indexer = (BaseIndexer)Activator.CreateInstance(Type.GetType(element.Type) 
                                , HttpContext.Current.Server.MapPath(PathUtil.GetIndexVirtualPath(provider)) 
                                , provider, true); 
                        try 
                        { 
                            foreach (IIndexFieldDetails dtls in indexer.IndexFields) 
                                if (!list.Contains(dtls.FieldName)) 
                                    list.Add(dtls.FieldName); 
                        } 
                        catch (Exception exc) 
                        { 
                            string error = exc.Message; 
                        } 
                        finally 
                        { 
                            if (indexer != null
                                indexer.Close(); 
                        } 
                    } 
                    arr = list.ToArray(); 
                    if (list.Count > 0) 
                        idxFlds.Add(provider, arr); 
                } 
                return arr; 
            } 
        } 

    Here you are filtering the results in the order you have created the index.

    Hits hits = searcher.Search(query, Sort.INDEXORDER); 
     

    So if you have created your indexes in the following order Pages, Blogs, News, you should get the Pages links firstly.

    Then you need to create another class and replace the default search results control with yours.

    namespace Telerik.Search.WebControls 
        /// <summary> 
        /// Summary description for CustomSearchResultToolboxItem 
        /// </summary> 
        public class CustomSearchResultToolboxItem : ToolboxItem 
        { 
            public CustomSearchResultToolboxItem() 
                : base(typeof(CustomSearchResult)) 
            { 
                this.DisplayName = "MyCustomSearchboxItem"
                this.Description = "CustomSearchResults_Description"
     
            } 
        } 

    I hope this helps.

    All the best,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. Gabe Sumner
    Gabe Sumner avatar
    440 posts
    Registered:
    09 Sep 2007
    10 Jun 2009
    Link to this post
    Hey Ivan,

    Does Sitefinity truly rank blog posts higher or is this just a coincidence?  I suspect Sitefinity doesn't lend special weight to specific content items (News, Events, Blogs, etc) but rather picks the page that looks most appropriate to the search algorithim.

    The code above describes how to emphasize specific content indexes (according to Index order), which is extremely fascinating and useful in some scenarios.  However, I suspect this might cause new problems since power is now being given to content that might not be the best match.

    I suppose it really depends on the results you're looking for.  If you want to bury blog posts, then the method above works.  The question I find facinating is; why do blog posts appear to rank higher?  Do these blog posts feature the search keywords more?  Can the existing low-ranking pages be enhanced by adding more keywords to the page content, description, url, image alt tags, etc?

    Annie, can you give us more details about the pages that aren't ranking highly in the search results?  Do the blog posts have more instances of the search keywords?

    Gabe Sumner
    http://www.sitefinitywatch.com/
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    10 Jun 2009
    Link to this post
    Hello Gabe Sumner,

    During paging matching results are returned. Generally there is no sorting Hits hits = searcher.Search(query), but you can use about 10 overloads.

    The available options are 
    //determines whether the object instances are equal
    Hits hits = searcher.Search(query, Sort.Equals);
    //sort by index order
    Hits hits = searcher.Search(query, Sort.INDEXORDER);
    //determines whether the object instances are the same
    Hits hits = searcher.Search(query, Sort.ReferenceEquals);
    //computing relevance, there is slightly overhead here
    Hits hits = searcher.Search(query, Sort.RELEVANCE)

    You can also force whether some of the search fields of a given index could have higher priority by setting weight attribute in \App_Data\Search\wwee\fieldsInfoProvider.xml ( -1 not searchable, 1 default value)

    Regards,

    Ivan Dimitrov
    the Telerik team

     


    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  5. Annie
    Annie avatar
    123 posts
    Registered:
    08 Apr 2009
    11 Jun 2009
    Link to this post
    Hi,

    Unfortunately the method given below wont work as we are using a custom search program created by an outside vendor (written in java) which uses the indexes created by Sitefinity. Is there any way of modifying the sitefinity indexing function to accomplish this?

    Thanks,
    Annie
  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    11 Jun 2009
    Link to this post
    Hi Annie,

    This is the way that you can use if you have custom search results control. There are some proviate methods of the SearchManager so returning the Searcher.Search value could be done only in the line in the sample.

    Greetings,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
Register for webinar
6 posts, 0 answered