Exemple #1
0
        /// <summary>
        /// Performs a search against a set of indexes.
        /// </summary>
        /// <param name="builder">The query to run against the indexes.</param>
        /// <param name="totalResultsRequested">The total number of results to return.</param>
        /// <returns>a list of <see cref="IndexLibrary.SearchResult"/>, one for each result found.</returns>
        /// <remarks>
        /// Designed to be used for the majority of searches. The functionality contained in this
        /// method is used for a normal search, i.e. enter a term, search, get results.
        /// </remarks>
        public virtual IEnumerable <SearchResult> Search(QueryBuilder builder, int totalResultsRequested)
        {
            if (builder == null)
            {
                throw new ArgumentNullException("builder", "builder cannot be null");
            }
            List <SearchResult> results = new List <SearchResult>();

            if (OnBeginSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Beginning, null)) || totalResultsRequested < -1 || totalResultsRequested == 0)
            {
                OnEndSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Ending, null));
                LibraryAnalysis.Fire(new SearchInfo(this.IndexNamesConcatenated, builder.ToString(), SearchMethodType.Normal, 0, true));
                return(results);
            }

            Lucene29.Net.Store.Directory             directory   = null;
            Lucene29.Net.Search.MultiSearcher        searcher    = null;
            List <Lucene29.Net.Search.IndexSearcher> searchables = null;
            int  hitsLength = 0;
            bool canceled   = false;

            try {
                searchables = new List <Lucene29.Net.Search.IndexSearcher>();
                for (int i = 0; i < this.indexes.Count; i++)
                {
                    DirectoryInfo searchInfo = null;
                    if (!GetIndexReadDirectory(this.indexes[i], out searchInfo))
                    {
                        continue;
                    }
                    searchables.Add(new Lucene29.Net.Search.IndexSearcher(Lucene29.Net.Store.FSDirectory.Open(searchInfo), true));
                }
                if (searchables.Count == 0)
                {
                    OnEndSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Ending, null));
                    return(results);
                }
                searcher = new Lucene29.Net.Search.MultiSearcher(searchables.ToArray());
                Lucene29.Net.Search.TopDocs topDocs = searcher.Search(builder.GetLuceneQuery, (totalResultsRequested == -1) ? StaticValues.DefaultDocsToReturn : totalResultsRequested);

                hitsLength = (totalResultsRequested == -1) ? topDocs.totalHits : Math.Min(topDocs.totalHits, totalResultsRequested);
                if (hitsLength > 5000)
                {
                    hitsLength = 5000;
                }
                int resultsFound = 0;
                for (int i = 0; i < hitsLength; i++)
                {
                    int      docID    = topDocs.scoreDocs[i].doc;
                    Document document = searcher.Doc(docID);
                    System.Collections.IList    fieldList = document.GetFields();
                    Dictionary <string, string> values    = new Dictionary <string, string>();
                    int totalValues = 0;
                    int totalFields = fieldList.Count;
                    for (int j = 0; j < totalFields; j++)
                    {
                        if (fieldList[j] == null)
                        {
                            continue;
                        }
                        Field field = fieldList[j] as Field;
                        values.Add(field.Name(), field.StringValue());
                        ++totalValues;
                    }
                    if (totalValues > 0)
                    {
                        SearchResult result = new SearchResult(values, string.Join(", ", this.IndexNames), topDocs.scoreDocs[i].score);
                        results.Add(result);
                        resultsFound++;
                        if (OnSearchResultFound(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Normal, SearchMethodLocation.ResultFound, result)))
                        {
                            canceled = true;
                            break;
                        }
                    }
                }
            }
            finally {
                if (searcher != null)
                {
                    searcher.Close();
                }
                if (searchables != null)
                {
                    searchables.ForEach(x => x.Close());
                }
                if (directory != null)
                {
                    directory.Close();
                }

                OnEndSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Ending, null));
                LibraryAnalysis.Fire(new SearchInfo(this.IndexNamesConcatenated, builder.ToString(), SearchMethodType.Normal, hitsLength, canceled));
            }

            return(results);
        }
Exemple #2
0
        /// <summary>
        /// Performs a full search against a set of indexes.
        /// </summary>
        /// <param name="builder">The query to run against the indexes.</param>
        /// <param name="totalResultsRequested">The total number of results to return.</param>
        /// <param name="fieldFilterNames">An exclusive list of fields to retrieve from the indexes.</param>
        /// <returns>A <see cref="IndexLibrary.SearchResultDataSet"/> that contains distinct values for each specified field and all search results</returns>
        /// <remarks>
        /// Used when you want to create filter type results such as http://www.kayak.com when you perform
        /// a search for an airline. A list of distinct values for all fields is displayed so you can filter down
        /// your results. This method performs the same functionality.
        /// </remarks>
        public virtual SearchResultDataSet FullSearch(QueryBuilder builder, int totalResultsRequested, string[] fieldFilterNames)
        {
            if (builder == null)
            {
                throw new ArgumentNullException("builder", "builder cannot be null");
            }
            SearchResultDataSet dataSet = new SearchResultDataSet();
            bool getAllFilters          = (fieldFilterNames == null || fieldFilterNames.Length == 0);

            if (OnBeginSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Beginning, null)) || totalResultsRequested < -1 || totalResultsRequested == 0)
            {
                OnEndSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Ending, null));
                LibraryAnalysis.Fire(new SearchInfo(this.IndexNamesConcatenated, builder.ToString(), SearchMethodType.Full, 0, true));
                return(dataSet);
            }

            Lucene29.Net.Store.Directory             directory   = null;
            Lucene29.Net.Search.MultiSearcher        searcher    = null;
            List <Lucene29.Net.Search.IndexSearcher> searchables = null;
            int  hitsLength = 0;
            bool canceled   = false;

            try {
                searchables = new List <Lucene29.Net.Search.IndexSearcher>();
                for (int i = 0; i < this.indexes.Count; i++)
                {
                    DirectoryInfo searchInfo = null;
                    if (!GetIndexReadDirectory(this.indexes[i], out searchInfo))
                    {
                        continue;
                    }
                    searchables.Add(new Lucene29.Net.Search.IndexSearcher(Lucene29.Net.Store.FSDirectory.Open(searchInfo), true));
                }

                if (searchables.Count == 0)
                {
                    OnEndSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Ending, null));
                    return(dataSet);
                }
                searcher = new Lucene29.Net.Search.MultiSearcher(searchables.ToArray());
                Lucene29.Net.Search.TopDocs topDocs = searcher.Search(builder.GetLuceneQuery, (totalResultsRequested == -1) ? StaticValues.DefaultDocsToReturn : totalResultsRequested);

                hitsLength = (totalResultsRequested == -1) ? topDocs.totalHits : Math.Min(topDocs.totalHits, totalResultsRequested);
                if (hitsLength > 5000)
                {
                    hitsLength = 5000;
                }
                int resultsFound = 0;
                for (int i = 0; i < hitsLength; i++)
                {
                    int      docID    = topDocs.scoreDocs[i].doc;
                    Document document = searcher.Doc(docID);
                    System.Collections.IList    fieldList = document.GetFields();
                    Dictionary <string, string> values    = new Dictionary <string, string>();
                    int totalValues = 0;
                    int totalFields = fieldList.Count;
                    for (int j = 0; j < totalFields; j++)
                    {
                        if (fieldList[j] == null)
                        {
                            continue;
                        }
                        Field  field = fieldList[j] as Field;
                        string name  = field.Name();
                        string value = field.StringValue();
                        field = null;

                        if (getAllFilters || fieldFilterNames.Contains(name))
                        {
                            SearchResultFilter filter = null;
                            if (!dataSet.ContainsFilter(name))
                            {
                                filter = new SearchResultFilter(name);
                                dataSet.AddFilter(filter);
                            }
                            else
                            {
                                filter = dataSet.GetFilter(name);
                            }

                            if (!filter.ContainsKey(value))
                            {
                                filter.AddValue(new KeyValuePair <string, bool>(value, true));
                            }
                        }

                        if (values.ContainsKey(name))
                        {
                            int revision = 1;
                            while (values.ContainsKey(name + "(" + revision.ToString() + ")"))
                            {
                                revision++;
                            }
                            name += "(" + revision.ToString() + ")";
                        }
                        values.Add(name, value);
                        ++totalValues;
                    }
                    if (totalValues > 0)
                    {
                        SearchResult result = new SearchResult(values, string.Join(", ", this.IndexNames), topDocs.scoreDocs[i].score);
                        dataSet.AddSearchResult(result);
                        resultsFound++;
                        if (OnSearchResultFound(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Full, SearchMethodLocation.ResultFound, result)))
                        {
                            canceled = true;
                            break;
                        }
                    }
                }
            }
            finally {
                if (searcher != null)
                {
                    searcher.Close();
                }
                if (searchables != null)
                {
                    searchables.ForEach(x => x.Close());
                }
                if (directory != null)
                {
                    directory.Close();
                }

                OnEndSearch(new MultiSearcherEventArgs(this.IndexNames, SearchMethodType.Quick, SearchMethodLocation.Ending, null));
                LibraryAnalysis.Fire(new SearchInfo(this.IndexNamesConcatenated, builder.ToString(), SearchMethodType.Full, hitsLength, canceled));
            }

            return(dataSet);
        }