Exemple #1
0
        /// <summary>
        /// Gets a subset of this instance based on the filter switches
        /// </summary>
        /// <param name="resetFilters">if set to <c>true</c> [reset filters] switches after retrieving subset.</param>
        /// <returns></returns>
        public SearchResultDataSet GetSubsetBasedOnFilters(bool resetFilters)
        {
            int totalFilters = this.filters.Count;
            int totalResults = this.searchResults.Count;

            if (totalFilters == 0 || totalResults == 0)
            {
                return(null);
            }
            SearchResultDataSet dataSet = new SearchResultDataSet();

            dataSet.AddSearchResultRange(this.searchResults);
            dataSet.AddFilterRange(this.filters);

            List <string> usedFilterValues = new List <string>();

            for (int i = 0; i < totalFilters; i++)
            {
                SearchResultFilter filter = dataSet.filters[i];
                foreach (KeyValuePair <string, bool> filterValue in filter.Values)
                {
                    if (!filterValue.Value)
                    {
                        dataSet.searchResults.RemoveAll(x => !string.IsNullOrEmpty(x.GetValue(filter.Name)) && x.GetValue(filter.Name) == filterValue.Key);
                        usedFilterValues.Add(filterValue.Key);
                        if (resetFilters)
                        {
                            this.filters[i].SetValue(filterValue.Key, true);
                        }
                    }
                }
                foreach (string usedValues in usedFilterValues)
                {
                    filter.RemoveValue(usedValues);
                }
                usedFilterValues.Clear();
            }
            usedFilterValues = null;
            return(dataSet);
        }
Exemple #2
0
        /// <summary>
        /// Retrieves data from this index.
        /// </summary>
        /// <param name="topNResults">The number of results to return from this index</param>
        /// <param name="buildFieldFiltersFromAllData">Specifies whether distinct values from all fields should be stored, even if all actual results are not returned from the index</param>
        /// <param name="filterFieldNames">The field names to build filters from</param>
        /// <returns>A <see cref="IndexLibrary.SearchResultDataSet"/> that contains all data from this index</returns>
        /// <remarks>
        /// filterFieldNames was added as a parameter to allow you to only pull data from specific fields into the filters,
        /// this can significantly increase the performance and the total amount of time required by this method.
        /// </remarks>
        public virtual SearchResultDataSet ReadDocuments(int topNResults, bool buildFieldFiltersFromAllData, string[] filterFieldNames)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("IndexReader", "You cannot call RetrieveIndex(int, string[], bool) from a disposed IndexReader");
            }
            if (topNResults == -1)
            {
                topNResults = this.TotalDocuments;
            }
            if (topNResults <= 0)
            {
                return(new SearchResultDataSet());
            }

            bool filterAll = (filterFieldNames == null || filterFieldNames.Length == 0);
            SearchResultDataSet dataSet = new SearchResultDataSet();
            int resultsToCollect        = this.TotalDocuments;

            if (OnBeginRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames)))
            {
                OnEndRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames));
                LibraryAnalysis.Fire(new ReadInfo(this.index.IndexDirectory.FullName, resultsToCollect, this.TotalDocuments, buildFieldFiltersFromAllData, this.IsOptimized));
                return(dataSet);
            }

            if (!buildFieldFiltersFromAllData && topNResults < this.TotalDocuments)
            {
                resultsToCollect = topNResults;
            }
            LibraryAnalysis.Fire(new ReadInfo(this.index.IndexDirectory.FullName, topNResults, this.TotalDocuments, buildFieldFiltersFromAllData, this.isDisposed));

            for (int i = 0; i < resultsToCollect; i++)
            {
                bool pastWantedResults = (buildFieldFiltersFromAllData && i >= topNResults);

                Lucene29.Net.Documents.Document document  = this.luceneReader.Document(i);
                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;
                    }
                    Lucene29.Net.Documents.Field field = fieldList[j] as Lucene29.Net.Documents.Field;
                    string name  = field.Name();
                    string value = field.StringValue();

                    if (filterAll || filterFieldNames.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);
                    if (OnReadResultFound(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames)))
                    {
                        OnEndRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames));
                        LibraryAnalysis.Fire(new ReadInfo(this.index.IndexDirectory.FullName, resultsToCollect, this.TotalDocuments, buildFieldFiltersFromAllData, this.IsOptimized));
                        return(dataSet);
                    }
                    ++totalValues;
                }
                if (totalValues > 0 && !pastWantedResults)
                {
                    dataSet.AddSearchResult(new SearchResult(values, this.index.IndexDirectory.FullName, 1f));
                }
            }

            OnEndRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames));

            return(dataSet);
        }
Exemple #3
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);
        }
        /// <summary>
        /// Retrieves data from this index.
        /// </summary>
        /// <param name="topNResults">The number of results to return from this index</param>
        /// <param name="buildFieldFiltersFromAllData">Specifies whether distinct values from all fields should be stored, even if all actual results are not returned from the index</param>
        /// <param name="filterFieldNames">The field names to build filters from</param>
        /// <returns>A <see cref="IndexLibrary.SearchResultDataSet"/> that contains all data from this index</returns>
        /// <remarks>
        /// filterFieldNames was added as a parameter to allow you to only pull data from specific fields into the filters,
        /// this can significantly increase the performance and the total amount of time required by this method.
        /// </remarks>
        public virtual SearchResultDataSet ReadDocuments(int topNResults, bool buildFieldFiltersFromAllData, string[] filterFieldNames)
        {
            if (this.isDisposed)
                throw new ObjectDisposedException("IndexReader", "You cannot call RetrieveIndex(int, string[], bool) from a disposed IndexReader");
            if (topNResults == -1)
                topNResults = this.TotalDocuments;
            if (topNResults <= 0)
                return new SearchResultDataSet();

            bool filterAll = (filterFieldNames == null || filterFieldNames.Length == 0);
            SearchResultDataSet dataSet = new SearchResultDataSet();
            int resultsToCollect = this.TotalDocuments;

            if (OnBeginRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames))) {
                OnEndRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames));
                LibraryAnalysis.Fire(new ReadInfo(this.index.IndexDirectory.FullName, resultsToCollect, this.TotalDocuments, buildFieldFiltersFromAllData, this.IsOptimized));
                return dataSet;
            }

            if (!buildFieldFiltersFromAllData && topNResults < this.TotalDocuments)
                resultsToCollect = topNResults;
            LibraryAnalysis.Fire(new ReadInfo(this.index.IndexDirectory.FullName, topNResults, this.TotalDocuments, buildFieldFiltersFromAllData, this.isDisposed));

            for (int i = 0; i < resultsToCollect; i++) {
                bool pastWantedResults = (buildFieldFiltersFromAllData && i >= topNResults);

                Lucene29.Net.Documents.Document document = this.luceneReader.Document(i);
                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;
                    Lucene29.Net.Documents.Field field = fieldList[j] as Lucene29.Net.Documents.Field;
                    string name = field.Name();
                    string value = field.StringValue();

                    if (filterAll || filterFieldNames.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);
                    if (OnReadResultFound(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames))) {
                        OnEndRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames));
                        LibraryAnalysis.Fire(new ReadInfo(this.index.IndexDirectory.FullName, resultsToCollect, this.TotalDocuments, buildFieldFiltersFromAllData, this.IsOptimized));
                        return dataSet;
                    }
                    ++totalValues;
                }
                if (totalValues > 0 && !pastWantedResults) {
                    dataSet.AddSearchResult(new SearchResult(values, this.index.IndexDirectory.FullName, 1f));
                }
            }

            OnEndRead(new ReaderEventArgs(this.index.IndexDirectory.FullName, topNResults, buildFieldFiltersFromAllData, filterFieldNames));

            return dataSet;
        }
        /// <summary>
        /// Gets a subset of this instance based on the filter switches
        /// </summary>
        /// <param name="resetFilters">if set to <c>true</c> [reset filters] switches after retrieving subset.</param>
        /// <returns></returns>
        public SearchResultDataSet GetSubsetBasedOnFilters(bool resetFilters)
        {
            int totalFilters = this.filters.Count;
            int totalResults = this.searchResults.Count;
            if (totalFilters == 0 || totalResults == 0)
                return null;
            SearchResultDataSet dataSet = new SearchResultDataSet();
            dataSet.AddSearchResultRange(this.searchResults);
            dataSet.AddFilterRange(this.filters);

            List<string> usedFilterValues = new List<string>();
            for (int i = 0; i < totalFilters; i++) {
                SearchResultFilter filter = dataSet.filters[i];
                foreach (KeyValuePair<string, bool> filterValue in filter.Values) {
                    if (!filterValue.Value) {
                        dataSet.searchResults.RemoveAll(x => !string.IsNullOrEmpty(x.GetValue(filter.Name)) && x.GetValue(filter.Name) == filterValue.Key);
                        usedFilterValues.Add(filterValue.Key);
                        if (resetFilters)
                            this.filters[i].SetValue(filterValue.Key, true);
                    }
                }
                foreach (string usedValues in usedFilterValues)
                    filter.RemoveValue(usedValues);
                usedFilterValues.Clear();
            }
            usedFilterValues = null;
            return dataSet;
        }