/// <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> /// 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; }