private TopDocs ExecuteQuery(Query documentQuery, int start, int pageSize, Sort sort)
        {
            if (sort == null && _indexHasBoostedFields == false && IsBoostedQuery(documentQuery) == false)
            {
                if (pageSize == int.MaxValue || pageSize >= _searcher.MaxDoc) // we want all docs, no sorting required
                {
                    var gatherAllCollector = new GatherAllCollector(Math.Min(pageSize, _searcher.MaxDoc));
                    _searcher.Search(documentQuery, gatherAllCollector, _state);
                    return(gatherAllCollector.ToTopDocs());
                }

                var noSortingCollector = new NonSortingCollector(Math.Abs(pageSize + start));

                _searcher.Search(documentQuery, noSortingCollector, _state);

                return(noSortingCollector.ToTopDocs());
            }

            var minPageSize = GetPageSize(_searcher, (long)pageSize + start);

            if (sort != null)
            {
                _searcher.SetDefaultFieldSortScoring(true, false);
                try
                {
                    return(_searcher.Search(documentQuery, null, minPageSize, sort, _state));
                }
                finally
                {
                    _searcher.SetDefaultFieldSortScoring(false, false);
                }
            }

            return(_searcher.Search(documentQuery, null, minPageSize, _state));
        }
Beispiel #2
0
        /// <summary>
        /// Open de Lucene index
        /// </summary>
        /// <returns></returns>
        protected virtual bool OpenIndex()
        {
            CDRLogger.FileLogger.LogInfo(String.Format("OpenIndex(): begin using path {0}", IndexName));
            bool result = false;

            if (index != null)
            {
                CloseIndex();
            }

            try
            {
                index = new IndexSearcher(IndexReader.Open(FSDirectory.Open(new System.IO.DirectoryInfo(indexBasePath)), true));
                index.SetDefaultFieldSortScoring(true, true);

                result = true;
            }
            catch (Exception e)
            {
                CDRLogger.Logger.LogInfo("CloseIndex(): " + e.Message);
                result = false;
                // voor de zekerheid!
                CloseIndex();
            }

            CDRLogger.FileLogger.LogInfo("OpenIndex(): end");
            return(result);
        }
Beispiel #3
0
        public override Searcher GetSearcher()
        {
            ValidateSearcher(false);

            //ensure scoring is turned on for sorting
            _searcher.SetDefaultFieldSortScoring(true, true);
            return(_searcher);
        }
Beispiel #4
0
        // main search method
        private static ResultObject _search(string searchQuery, int pad, string searchField = "")
        {
            // validation
            if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
            {
                return(new ResultObject());
            }

            // set up lucene searcher
            using (var searcher = new IndexSearcher(_directory, false))
            {
                var hits_limit = 10000;
                var analyzer   = new StandardAnalyzer(Version.LUCENE_30);

                int start = (pad - 1) * hitsPerPage;
                int end   = start + hitsPerPage;


                var parser = new MultiFieldQueryParser
                                 (Version.LUCENE_30, new[] { "Contents", "Title" }, analyzer);
                var query = parseQuery(searchQuery, parser);
                // return all scoredoc for all searched document
                searcher.SetDefaultFieldSortScoring(true, true);
                var sort = new Sort(new SortField("Contents", SortField.SCORE));
                var hits = searcher.Search(query, null, hits_limit, sort).ScoreDocs;

                ResultObject results = new ResultObject();
                List <CustomresultObject> listsite = new List <CustomresultObject>();
                for (int i = start; i < Math.Min(end, hits.Length); ++i)
                {
                    listsite.Add(_mapLuceneToDataList(hits[i], searcher, query, analyzer));
                }
                results.sites         = listsite;
                results.NumberResult  = hits.Length;
                results.Resultperpage = hitsPerPage;
                analyzer.Close();
                searcher.Dispose();
                // WRITE LOG
                string datenow = DateTime.Now.ToString("h:mm:ss tt");
                string path    = @"D:\MyTest.txt";
                // This text is added only once to the file.
                if (!File.Exists(path))
                {
                    // Create a file to write to.
                    string createText = "Time: " + datenow + "|query: " + searchQuery + "|Resultnum: " + hits.Length + Environment.NewLine;
                    File.WriteAllText(path, createText);
                }

                // This text is always added, making the file longer over time
                // if it is not deleted.
                string appendText = "Time: " + datenow + "|query: " + searchQuery + "|Resultnum: " + hits.Length + Environment.NewLine;
                File.AppendAllText(path, appendText);


                return(results);
            }
        }
Beispiel #5
0
        private static List <Document> doSearch(string text)
        {
            //string text = RemoveControlCharsFromString(textSearch);
            if (text == null || text == "" || text.Contains('\n') || text.Contains('\t') || text.Contains('\r') || text.Contains('\b'))
            {
                return(null);
            }
            //The array-list of title strings for the matching results
            List <Document> list = new List <Document>();

            //The IndexReader reads the index table -- opens the directory(IN MEMORY)
            IndexReader reader = IndexReader.Open(dir, true);
            //The indexSearcher is used to search for matches
            IndexSearcher searcher = new IndexSearcher(reader);

            searcher.SetDefaultFieldSortScoring(true, false);
            //Similarity -- relevence
            searcher.Similarity = new DefaultSimilarity();
            //The analyzer -- Maybe it has something to do with the relevence
            StandardAnalyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);


            MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, new string[] { "ad_id", "ad_title", "ad_desc" }, analyzer);

            //The queryParser defines which fields are to be used for the search


            //True so we can use wildcards in the search *
            queryParser.AllowLeadingWildcard = true;
            //Used when searching now it matches results if the hit has one of the words
            //example: "the house" will match only in text with both words
            queryParser.DefaultOperator = QueryParser.OR_OPERATOR;
            //A query is being created with the given text

            Query query = queryParser.Parse(text);


            TopScoreDocCollector collector = TopScoreDocCollector.Create(1000, true);

            searcher.Search(query, collector);
            ScoreDoc[] matches = collector.TopDocs().ScoreDocs;


            //Itereate in matches array
            foreach (ScoreDoc item in matches)
            {
                int id = item.Doc;
                //search by id in the index table -- very fast
                Document doc = searcher.Doc(id);
                //We add the document to the list
                list.Add(doc);
            }

            //the list is always with order by score
            return(list);
        }
Beispiel #6
0
        public IndexSearcher CreateSearcher(bool readOnly, bool calcScore)
        {
            var result = new IndexSearcher(Directory, readOnly);

            if (calcScore)
            {
                result.SetDefaultFieldSortScoring(true, true);
            }
            return(result);
        }
 public override Searcher GetSearcher()
 {
     if (_searcher == null)
     {
         _searcher = new IndexSearcher(GetLuceneDirectory(), true);
     }
     //ensure scoring is turned on for sorting
     _searcher.SetDefaultFieldSortScoring(true, true);
     return(_searcher);
 }
        // поиск с указанием найденной позиции в тексте
        public void DoSearch(String db, String querystr, global::Lucene.Net.Store.Directory indexDirectory)
        {
            // 1. Specify the analyzer for tokenizing text.
            //    The same analyzer should be used as was used for indexing
            StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_30, ListStopWords);


            // 2. query
            Query q = new QueryParser(Version.LUCENE_30, "LineText", analyzer).Parse(querystr);

            // 3. search
            int           hitsPerPage = 10;
            IndexSearcher searcher    = new IndexSearcher(indexDirectory, true);
            IndexReader   reader      = IndexReader.Open(indexDirectory, true);

            searcher.SetDefaultFieldSortScoring(true, false);
            TopScoreDocCollector collector = TopScoreDocCollector.Create(hitsPerPage, true);

            searcher.Search(q, collector);
            ScoreDoc[] hits = collector.TopDocs().ScoreDocs;

            // 4. display term positions, and term indexes
            MessageBox.Show("Found " + hits.Length + " hits.");

            for (int i = 0; i < hits.Length; ++i)
            {
                int                docId    = hits[i].Doc;
                ITermFreqVector    tfvector = reader.GetTermFreqVector(docId, "LineText");
                TermPositionVector tpvector = (TermPositionVector)tfvector;
                // this part works only if there is one term in the query string,
                // otherwise you will have to iterate this section over the query terms.
                int   termidx  = tfvector.IndexOf(querystr);
                int[] termposx = tpvector.GetTermPositions(termidx);
                TermVectorOffsetInfo[] tvoffsetinfo = tpvector.GetOffsets(termidx);

                for (int j = 0; j < termposx.Length; j++)
                {
                    MessageBox.Show("termpos : " + termposx[j]);
                }
                for (int j = 0; j < tvoffsetinfo.Length; j++)
                {
                    int offsetStart = tvoffsetinfo[j].StartOffset;
                    int offsetEnd   = tvoffsetinfo[j].EndOffset;
                    MessageBox.Show("offsets : " + offsetStart + " " + offsetEnd);
                }

                // print some info about where the hit was found...
                Document d = searcher.Doc(docId);
                MessageBox.Show((i + 1) + ". " + d.Get("path"));
            }

            // searcher can only be closed when there
            // is no need to access the documents any more.
            searcher.Dispose();
        }
        /// <summary>
        /// Gets the searcher for this instance, this method will also ensure that the searcher is up to date whenever this method is called.
        /// </summary>
        /// <returns>
        /// Returns null if the underlying index doesn't exist
        /// </returns>
        public override Searcher GetLuceneSearcher()
        {
            if (!ValidateSearcher())
            {
                return(null);
            }

            //ensure scoring is turned on for sorting
            _searcher.SetDefaultFieldSortScoring(true, true);
            return(_searcher);
        }
Beispiel #10
0
        public LuceneDotNetHowToExamplesFacade setIndexSearcherFieldSortScoring(bool doTrackScores, bool doMaxScore)
        {
            if (IndexSearcher == null)
            {
                throw new Exception("IndexParser not created.");
            }

            IndexSearcher.SetDefaultFieldSortScoring(doTrackScores, doMaxScore);

            return(this);
        }
Beispiel #11
0
        // main search method
        private static IEnumerable <LuceneSearchModel> _search(string searchQuery, int amountToTake, string searchField = "")
        {
            // validation
            if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
            {
                return(new List <LuceneSearchModel>());
            }

            // set up lucene searcher
            using (var searcher = new IndexSearcher(_directory, false))
            {
                const int hitsLimit = 1000;
                var       analyzer  = new StandardAnalyzer(Version.LUCENE_30);

                // search by single field
                if (!string.IsNullOrEmpty(searchField))
                {
                    var parser = new QueryParser(Version.LUCENE_30, searchField, analyzer);
                    var query  = parseQuery(searchQuery, parser);
                    searcher.SetDefaultFieldSortScoring(true, true);
                    var hits    = searcher.Search(query, hitsLimit).ScoreDocs;
                    var results = _mapLuceneToDataList(hits, searcher, amountToTake);
                    analyzer.Close();
                    searcher.Dispose();
                    return(results);
                }
                // search by multiple fields (ordered by RELEVANCE)
                else
                {
                    var parser = new MultiFieldQueryParser(Version.LUCENE_30, new[] { AppConstants.LucId, AppConstants.LucTopicName, AppConstants.LucPostContent }, analyzer);
                    var query  = parseQuery(searchQuery, parser);
                    searcher.SetDefaultFieldSortScoring(true, true);
                    var hits    = searcher.Search(query, null, hitsLimit, Sort.INDEXORDER).ScoreDocs;
                    var results = _mapLuceneToDataList(hits, searcher, amountToTake);
                    analyzer.Close();
                    searcher.Dispose();
                    return(results);
                }
            }
        }
Beispiel #12
0
        private TopDocs ExecuteQuery(Query documentQuery, int start, int pageSize, Sort sort)
        {
            if (sort == null && _indexHasBoostedFields == false && IsBoostedQuery(documentQuery) == false)
            {
                if (pageSize == int.MaxValue) // we want all docs, no sorting required
                {
                    var gatherAllCollector = new GatherAllCollector();
                    _searcher.Search(documentQuery, gatherAllCollector);
                    return(gatherAllCollector.ToTopDocs());
                }

                var noSortingCollector = new NonSortingCollector(Math.Abs(pageSize + start));

                _searcher.Search(documentQuery, noSortingCollector);

                return(noSortingCollector.ToTopDocs());
            }

            var absFullPage = Math.Abs(pageSize + start); // need to protect against ridiculously high values of pageSize + start that overflow
            var minPageSize = Math.Max(absFullPage, 1);

            if (sort != null)
            {
                _searcher.SetDefaultFieldSortScoring(true, false);
                try
                {
                    return(_searcher.Search(documentQuery, null, minPageSize, sort));
                }
                finally
                {
                    _searcher.SetDefaultFieldSortScoring(false, false);
                }
            }

            return(_searcher.Search(documentQuery, null, minPageSize));
        }
        /// <summary>
        /// Get the configuration details of an Exmaine searcher, so Lucene can be queried in the same way,
        /// consumer needs to know Lucene directory, the analyser (for the text field) and whether to use wildcards)
        /// TODO: move validation logic out into initialize, so quicker to get content during a query
        /// </summary>
        /// <param name="searcherName">The name of the Examine seracher (see ExamineSettings.config)</param>
        /// <returns>SearchingContext if found, otherwise null</returns>
        private static SearchingContext GetSearchingContext(string searcherName)
        {
            LuceneSearcher searcher = null;

            if (string.IsNullOrWhiteSpace(searcherName))
            {
                searcher = ExamineManager.Instance.DefaultSearchProvider as LuceneSearcher;
            }
            else
            {
                searcher = ExamineManager.Instance.SearchProviderCollection[searcherName] as LuceneSearcher;

                if (searcher == null && !searcherName.EndsWith("Searcher"))
                {
                    searcher = ExamineManager.Instance.SearchProviderCollection[searcherName + "Searcher"] as LuceneSearcher;
                }
            }

            if (searcher == null)
            {
                LogHelper.Debug(typeof(LookService), $"Unable to find Examine Lucene Searcher '{ searcherName }'");
            }
            else
            {
                var indexSetDirectory = LookService.Instance.IndexSetDirectories[searcher.IndexSetName];

                if (indexSetDirectory != null)
                {
                    var indexSearcher = new IndexSearcher(indexSetDirectory, true); // TODO: handle reuse
                    indexSearcher.SetDefaultFieldSortScoring(true, true);

                    return(new SearchingContext()
                    {
                        Analyzer = searcher.IndexingAnalyzer,
                        IndexSearcher = indexSearcher,
                        EnableLeadingWildcards = searcher.EnableLeadingWildcards
                    });
                }
            }

            return(null);
        }
Beispiel #14
0
        private static IEnumerable <LuceneData_BO> _searchFrontEnd(string searchQuery, string searchField = "")
        {
            // validation
            if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
            {
                return(new List <LuceneData_BO>());
            }

            // set up lucene searcher
            using (var searcher = new IndexSearcher(_directoryFrontEnd, false))
            {
                var hits_limit = 1000;
                var analyzer   = new StandardAnalyzer(Version.LUCENE_30);

                // search by single field
                if (!string.IsNullOrEmpty(searchField))
                {
                    var parser  = new QueryParser(Version.LUCENE_30, searchField, analyzer);
                    var query   = parseQuery(searchQuery, parser);
                    var hits    = searcher.Search(query, hits_limit).ScoreDocs;
                    var results = _mapLuceneToDataList(hits, searcher);
                    analyzer.Close();
                    searcher.Dispose();
                    return(results);
                }
                // search by multiple fields (ordered by RELEVANCE)
                else
                {
                    var parser = new MultiFieldQueryParser
                                     (Version.LUCENE_30, new[] { "Title", "Url", "Description" }, analyzer);
                    var query = parseQuery(searchQuery, parser);
                    searcher.SetDefaultFieldSortScoring(true, true);
                    var hits    = searcher.Search(query, null, hits_limit, Sort.RELEVANCE).ScoreDocs;
                    var results = _mapLuceneToDataList(hits, searcher);
                    analyzer.Close();
                    searcher.Dispose();
                    return(results);
                }
            }
        }
Beispiel #15
0
        private static IEnumerable <Offer> _search(string searchQuery, string searchField = "")
        {
            // validation
            if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
            {
                return(new List <Offer>());
            }

            // set up lucene searcher
            using (var searcher = new IndexSearcher(_directory, true))
            {
                var hits_limit = 1000;
                //var analyzer = new StandardAnalyzer(Version.LUCENE_30);
                var analyzer = new SnowballAnalyzer(Lucene.Net.Util.Version.LUCENE_30, "English", StopAnalyzer.ENGLISH_STOP_WORDS_SET);
                searcher.SetDefaultFieldSortScoring(true, true);

                // search by single field
                if (!string.IsNullOrEmpty(searchField))
                {
                    var parser  = new QueryParser(Version.LUCENE_30, searchField, analyzer);
                    var query   = parseQuery(searchQuery, parser);
                    var hits    = searcher.Search(query, hits_limit).ScoreDocs;
                    var results = _mapLuceneToOfferList(hits, searcher);
                    analyzer.Close();
                    searcher.Dispose();
                    return(results);
                }
                // search by multiple fields (ordered by RELEVANCE)
                else
                {
                    var parser  = new MultiFieldQueryParser(Version.LUCENE_30, _fields.Keys.ToArray(), analyzer);
                    var query   = parseQuery(searchQuery, parser);
                    var hits    = searcher.Search(query, null, hits_limit, Sort.RELEVANCE).ScoreDocs;
                    var results = _mapLuceneToOfferList(hits, searcher);
                    analyzer.Close();
                    searcher.Dispose();
                    return(results);
                }
            }
        }
Beispiel #16
0
        private static IEnumerable <Offer> _fuzzysearch(string searchQuery, string searchField)
        {
            // validation
            if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
            {
                return(new List <Offer>());
            }

            // set up lucene searcher
            using (var searcher = new IndexSearcher(_directory, true))
            {
                var hits_limit = 1000;
                searcher.SetDefaultFieldSortScoring(true, true);

                // search by single field for fuzzy
                var query   = fuzzyParseQuery(searchQuery);
                var hits    = searcher.Search(query, hits_limit).ScoreDocs;
                var results = _mapLuceneToOfferList(hits, searcher);
                searcher.Dispose();
                return(results);
            }
        }
        public ActionResult ArtistSearch(string term)
        {
            Analyzer analyzer   = new ASCIIFoldingAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
            var      hits_limit = 5000;

            BooleanQuery  finalQuery = getPrefixQuery(Constants.ARTIST_FIELD, 3, term, analyzer);
            IndexSearcher searcher   = getSearcher();

            searcher.SetDefaultFieldSortScoring(true, true);
            ScoreDoc[] hits      = searcher.Search(finalQuery, null, hits_limit, Sort.RELEVANCE).ScoreDocs;
            ScoreDoc[] fuzzyHits = searcher.Search(getFuzzyQuery(Constants.ARTIST_FIELD, term, analyzer),
                                                   null, hits_limit, Sort.RELEVANCE).ScoreDocs;

            List <String> searchResults = new List <String>();

            foreach (ScoreDoc hit in hits)
            {
                var    document = searcher.IndexReader.Document(hit.Doc);
                string artist   = document.Get(Constants.ARTIST_FIELD);
                if (!searchResults.Contains(artist))
                {
                    searchResults.Add(document.Get(Constants.ARTIST_FIELD));
                }
            }

            foreach (ScoreDoc hit in fuzzyHits)
            {
                var    document = searcher.IndexReader.Document(hit.Doc);
                string artist   = document.Get(Constants.ARTIST_FIELD);
                if (!searchResults.Contains(artist))
                {
                    searchResults.Add(document.Get(Constants.ARTIST_FIELD));
                }
            }

            searcher.Dispose();
            return(Json(searchResults.ToArray().Take(10)));
        }
Beispiel #18
0
        private static PagedList <LuceneSearchModel> _search(string searchQuery, int pageIndex, int pageSize)
        {
            // validation
            if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
            {
                return(null);
            }
            // set up lucene searcher
            using (var searcher = new IndexSearcher(_directory, false))
            {
                const int hitsLimit = 1000;
                var       analyzer  = new StandardAnalyzer(Version.LUCENE_30);

                var parser = new MultiFieldQueryParser(Version.LUCENE_30, new[] { AppConstants.LucId, AppConstants.LucTopicName, AppConstants.LucPostContent }, analyzer);
                var query  = parseQuery(searchQuery, parser);
                searcher.SetDefaultFieldSortScoring(true, true);
                var hits    = searcher.Search(query, null, hitsLimit, Sort.INDEXORDER).ScoreDocs;
                var results = _mapLuceneToDataList(hits, searcher, pageIndex, pageSize);
                analyzer.Close();
                searcher.Dispose();
                return(results);
            }
        }
Beispiel #19
0
        // search methods
        public static IEnumerable <LuceneSearchModel> GetAllIndexRecords()
        {
            // validate search index
            if (!System.IO.Directory.EnumerateFiles(_luceneDir).Any())
            {
                return(new List <LuceneSearchModel>());
            }

            // set up lucene searcher
            var searcher = new IndexSearcher(_directory, false);
            var reader   = IndexReader.Open(_directory, false);

            searcher.SetDefaultFieldSortScoring(true, true);
            var docs = new List <Document>();
            var term = reader.TermDocs();

            while (term.Next())
            {
                docs.Add(searcher.Doc(term.Doc));
            }
            reader.Dispose();
            searcher.Dispose();
            return(_mapLuceneToDataList(docs));
        }
        public static IndexSearcher BuildSearcher(ISearchFactoryImplementor searchFactory,
                                                  out ISet <System.Type> classesAndSubclasses,
                                                  params System.Type[] classes)
        {
            IDictionary <System.Type, DocumentBuilder> builders = searchFactory.DocumentBuilders;
            ISet <IDirectoryProvider> directories = new HashSet <IDirectoryProvider>();

            if (classes == null || classes.Length == 0)
            {
                // no class means all classes
                foreach (DocumentBuilder builder in builders.Values)
                {
                    foreach (IDirectoryProvider provider in builder.DirectoryProvidersSelectionStrategy.GetDirectoryProvidersForAllShards())
                    {
                        directories.Add(provider);
                    }
                }

                // Give them back an empty set
                classesAndSubclasses = null;
            }
            else
            {
                ISet <System.Type> involvedClasses = new HashSet <System.Type>();
                involvedClasses.AddAll(classes);
                foreach (System.Type clazz in classes)
                {
                    DocumentBuilder builder;
                    builders.TryGetValue(clazz, out builder);
                    if (builder != null)
                    {
                        involvedClasses.AddAll(builder.MappedSubclasses);
                    }
                }

                foreach (System.Type clazz in involvedClasses)
                {
                    DocumentBuilder builder;
                    builders.TryGetValue(clazz, out builder);

                    // TODO should we rather choose a polymorphic path and allow non mapped entities
                    if (builder == null)
                    {
                        throw new HibernateException("Not a mapped entity: " + clazz);
                    }

                    foreach (IDirectoryProvider provider in builder.DirectoryProvidersSelectionStrategy.GetDirectoryProvidersForAllShards())
                    {
                        directories.Add(provider);
                    }
                }

                classesAndSubclasses = involvedClasses;
            }

            IDirectoryProvider[] directoryProviders = new List <IDirectoryProvider>(directories).ToArray();

            var searcher = new IndexSearcher(searchFactory.ReaderProvider.OpenReader(directoryProviders));

            searcher.SetDefaultFieldSortScoring(true, true);

            return(searcher);
        }
        /// <summary>
        /// core search method
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        protected IXQueryCollection DoSearch(IXRequest request)
        {
            // validation
            if (String.IsNullOrEmpty(request.Query.Replace("*", "").Replace("?", "")))
            {
                return new IXQueryCollection()
                       {
                           Count = 0, Start = 0, Take = 0, Results = new IXQuery[] { }, Status = IXQueryStatus.ErrorQuerySyntax
                       }
            }
            ;

            QueryParser parser = null;

            if (request.Fields.Count() < 1)
            {
                parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, null, analyzer);
            }
            else if (request.Fields.Count() == 1)
            {
                parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, request.Fields.ElementAt(0), analyzer);
            }
            else
            {
                parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, request.Fields.ToArray(), analyzer);
            }

            Query query = ParseQuery(request.Query, parser);

            if (query == null)
            {
                return new IXQueryCollection()
                       {
                           Count = 0, Start = 0, Take = 0, Results = new IXQuery[] { }, Status = IXQueryStatus.ErrorQuerySyntax
                       }
            }
            ;;

            bool useScoring = ((request.Flags & IXRequestFlags.UseScore) == IXRequestFlags.UseScore);

            if (useScoring)
            {
                indexSearcher.SetDefaultFieldSortScoring(true, true);
            }
            else
            {
                indexSearcher.SetDefaultFieldSortScoring(false, false);
            }

            TopFieldDocs hits = indexSearcher.Search(query, null, this.MaxSearchHits, Sort.RELEVANCE);

            int skip = request.Skip;
            int take = request.Take;

            if (skip < 0)
            {
                skip = 0;
            }

            if (take < 1)
            {
                take = this.MaxSearchHits;
            }

            return(new IXQueryCollection
            {
                Results = MapLuceneIndexToDataList(hits.ScoreDocs.Skip(skip).Take(take), indexSearcher, useScoring, request.Fields),
                Start = skip,
                Take = take,
                Count = hits.TotalHits,
                Status = (hits.TotalHits > 0) ? IXQueryStatus.Success : IXQueryStatus.NoData
            });
        }
        private ILuceneSearchResultCollection PerformSearch(SearchOptions options, bool safeSearch)
        {
            // Results collection
            ILuceneSearchResultCollection results = new LuceneSearchResultCollection();

            using (var reader = IndexReader.Open(directory, true))
                using (var searcher = new IndexSearcher(reader))
                {
                    Query query;

                    // calculate the scores - this has a cpu hit!!!
                    searcher.SetDefaultFieldSortScoring(true, true);

                    // Escape our search if we're performing a safe search
                    if (safeSearch == true)
                    {
                        options.SearchText = QueryParser.Escape(options.SearchText);
                    }

                    if (options.Fields.Count() == 1)
                    {
                        // Single field search
                        QueryParser queryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, options.Fields[0], analyzer);
                        query = queryParser.Parse(options.SearchText);
                    }
                    else
                    {
                        // Parse the boosts against the fields

                        // Multifield search
                        MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, options.Fields.ToArray(), analyzer, options.Boosts);
                        query = multiFieldQueryParser.Parse(options.SearchText);
                    }

                    List <SortField> sortFields = new List <SortField>();
                    sortFields.Add(SortField.FIELD_SCORE);

                    // if we have any sort fields then add them
                    foreach (var sortField in options.OrderBy)
                    {
                        sortFields.Add(new SortField(sortField, SortField.STRING));
                    }

                    // create our sort
                    Sort sort = new Sort(sortFields.ToArray());

                    ScoreDoc[] matches = searcher.Search(query, null, options.MaximumNumberOfHits, sort).ScoreDocs;

                    results.TotalHits = matches.Count();

                    // perform skip and take if needed
                    if (options.Skip.HasValue)
                    {
                        matches = matches.Skip(options.Skip.Value).ToArray();
                    }
                    if (options.Take.HasValue)
                    {
                        matches = matches.Take(options.Take.Value).ToArray();
                    }

                    // create a list of documents from the results
                    foreach (var match in matches)
                    {
                        var id  = match.Doc;
                        var doc = searcher.Doc(id);

                        // filter out unwanted documents if a type has been set
                        if (options.Type != null)
                        {
                            var t = doc.Get("Type");
                            if (options.Type.AssemblyQualifiedName == t)
                            {
                                results.Results.Add(new LuceneSearchResult()
                                {
                                    Score    = match.Score,
                                    Document = doc
                                });
                            }
                        }
                        else
                        {
                            results.Results.Add(new LuceneSearchResult()
                            {
                                Score    = match.Score,
                                Document = doc
                            });
                        }
                    }
                }

            return(results);
        }