Represents a search result.
Instance and static members are not thread-safe.
예제 #1
0
        /// <summary>
        /// Creates a new instance of the <see cref="T:SearchResultRow" /> class.
        /// </summary>
        /// <param name="result">The result to use.</param>
        /// <returns>The instance.</returns>
        public static SearchResultRow CreateInstance(SearchResult result)
        {
            string queryStringKeywords = "HL=" + GetKeywordsForQueryString(result.Matches);

            if(result.Document.TypeTag == PageDocument.StandardTypeTag) {
                PageDocument pageDoc = result.Document as PageDocument;

                return new SearchResultRow(pageDoc.PageInfo.FullName + Settings.PageExtension + "?" + queryStringKeywords, Page,
                    FormattingPipeline.PrepareTitle(pageDoc.Title, false, FormattingContext.PageContent, pageDoc.PageInfo),
                    result.Relevance.Value, GetExcerpt(pageDoc.PageInfo, result.Matches));
            }
            else if(result.Document.TypeTag == MessageDocument.StandardTypeTag) {
                MessageDocument msgDoc = result.Document as MessageDocument;

                PageContent content = Content.GetPageContent(msgDoc.PageInfo, true);

                return new SearchResultRow(msgDoc.PageInfo.FullName + Settings.PageExtension + "?" + queryStringKeywords +"&amp;Discuss=1#" + Tools.GetMessageIdForAnchor(msgDoc.DateTime), Message,
                    FormattingPipeline.PrepareTitle(msgDoc.Title, false, FormattingContext.MessageBody, content.PageInfo) + " (" +
                    FormattingPipeline.PrepareTitle(content.Title, false, FormattingContext.MessageBody, content.PageInfo) +
                    ")", result.Relevance.Value, GetExcerpt(msgDoc.PageInfo, msgDoc.MessageID, result.Matches));
            }
            else if(result.Document.TypeTag == FileDocument.StandardTypeTag) {
                FileDocument fileDoc = result.Document as FileDocument;

                return new SearchResultRow("GetFile.aspx?File=" + Tools.UrlEncode(fileDoc.Name.Substring(fileDoc.Provider.Length + 1)) +
                    "&amp;Provider=" + Tools.UrlEncode(fileDoc.Provider),
                    File, fileDoc.Title, result.Relevance.Value, "");
            }
            else if(result.Document.TypeTag == PageAttachmentDocument.StandardTypeTag) {
                PageAttachmentDocument attnDoc = result.Document as PageAttachmentDocument;
                PageContent content = Content.GetPageContent(attnDoc.Page, false);

                return new SearchResultRow(attnDoc.Page.FullName + Settings.PageExtension, Attachment,
                    attnDoc.Title + " (" +
                    FormattingPipeline.PrepareTitle(content.Title, false, FormattingContext.PageContent, content.PageInfo) +
                    ")", result.Relevance.Value, "");
            }
            else throw new NotSupportedException();
        }
예제 #2
0
파일: Tools.cs 프로젝트: mono/ScrewTurnWiki
        /// <summary>
        /// Performs a search in the index.
        /// </summary>
        /// <param name="query">The search query.</param>
        /// <param name="documentTypeTags">The document type tags to include in the search.</param>
        /// <param name="filterDocumentType"><c>true</c> to apply the filter on the document type.</param>
        /// <param name="options">The search options.</param>
        /// <param name="fetcher">An object that is able to fetch words.</param>
        /// <returns>The results.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="query"/> or <paramref name="fetcher"/> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="query"/> is empty.</exception>
        /// <exception cref="ArgumentNullException">If <paramref name="filterDocumentType"/> is <c>true</c> and <paramref name="documentTypeTags"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="filterDocumentType"/> is <c>true</c> and <paramref name="documentTypeTags"/> is empty.</exception>
        public static SearchResultCollection SearchInternal(string query, string[] documentTypeTags, bool filterDocumentType, SearchOptions options, IWordFetcher fetcher)
        {
            if(query == null) throw new ArgumentNullException("query");
            if(query.Length == 0) throw new ArgumentException("Query cannot be empty", "query");

            if(filterDocumentType && documentTypeTags == null) throw new ArgumentNullException("documentTypeTags");
            if(filterDocumentType && documentTypeTags.Length == 0) throw new ArgumentException("documentTypeTags cannot be empty", "documentTypeTags");

            if(fetcher == null) throw new ArgumentNullException("fetcher");

            SearchResultCollection results = new SearchResultCollection();

            query = query.ToLowerInvariant();
            string[] queryWords = query.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            float totalRelevance = 0;

            Word word = null;
            foreach(string q in queryWords) {
                if(fetcher.TryGetWord(q, out word)) {
                    foreach(IDocument doc in word.Occurrences.Keys) {
                        // Skip documents with excluded tags
                        if(filterDocumentType &&
                            !IsDocumentTypeTagIncluded(doc.TypeTag, documentTypeTags)) continue;
                        foreach(BasicWordInfo info in word.Occurrences[doc]) {
                            // If a search result is already present, add a new match to it,
                            // otherwise create a new search result object
                            WordInfo mi = new WordInfo(q, info.FirstCharIndex, info.WordIndex, info.Location);
                            SearchResult res = results.GetSearchResult(doc);
                            if(res == null) {
                                res = new SearchResult(doc);
                                res.Relevance.SetValue(info.Location.RelativeRelevance);
                                res.Matches.Add(mi);
                                results.Add(res);
                            }
                            else {
                                // Avoid adding duplicate matches (happens when query contains the same word multiple times)
                                if(!res.Matches.ContainsOccurrence(mi.Text, mi.FirstCharIndex)) {
                                    res.Matches.Add(mi);
                                }
                                res.Relevance.SetValue(res.Relevance.Value + info.Location.RelativeRelevance);
                            }
                            totalRelevance += info.Location.RelativeRelevance;
                        }
                    }
                }
            }

            if(options == SearchOptions.AllWords) {
                totalRelevance -= PurgeResultsForAllWords(results, queryWords);
            }
            else if(options == SearchOptions.ExactPhrase) {
                totalRelevance -= PurgeResultsForExactPhrase(results, queryWords);
            }
            else if(options == SearchOptions.AtLeastOneWord) {
                // Nothing to do
            }
            else throw new InvalidOperationException("Unsupported SearchOptions");

            // Finalize relevance values
            for(int i = 0; i < results.Count; i++) {
                results[i].Relevance.Finalize(totalRelevance);
            }

            return results;
        }