| 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<string, string[]> idxFlds = new Dictionary<string, string[]>(); |
| |
| 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; |
| } |
| } |
| } |