/// <summary> /// Performs a boolean search into a location circle area /// </summary> /// <param name="SearchTermFields">Query input</param> /// <param name="page">Results Page</param> /// <param name="ResultsPerPage">Results per page</param> /// <param name="limit">limit result default is 20</param> /// <returns>Query result</returns> internal SearchResults <T> Search(IEnumerable <SearchTerm> SearchTermFields, int page, int ResultsPerPage, int limit = 500, List <SortField> sorting = null) { //System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); //stopWatch.Start(); QueryDesriptor query = SearchTermQuery(SearchTermFields); Sort sort; if (sorting == null) { if (query.InArea) { sort = new Sort(new SortField("Distance", SortFieldType.SCORE, true)); } else { sort = Sort.RELEVANCE; } } else { if (query.InArea) { sorting.Add(new SortField("Distance", SortFieldType.SCORE, true)); } sort = new Sort(sorting.ToArray()); } ScoreDoc[] hits; if (query.InArea) { TopDocs topDocs = Searcher.Search(query.Query, query.Filter, limit, sort); hits = topDocs.ScoreDocs; } else { hits = Searcher.Search(query.Query, null, limit, sort).ScoreDocs; } //stopWatch.Stop(); // Get the elapsed time as a TimeSpan value. //TimeSpan ts = stopWatch.Elapsed; //System.Diagnostics.Debug.WriteLine(ts); return(PageResult(hits, page, ResultsPerPage, query.SpatialArguments)); }
/// <summary> /// Constracts a boolean query from a searchterm dictionary /// </summary> /// <param name="SearchTermFields"></param> /// <returns></returns> private QueryDesriptor SearchTermQuery(IEnumerable <SearchTerm> SearchTermFields) { QueryDesriptor descriptor = new QueryDesriptor(); BooleanQuery query = new BooleanQuery(); Query areaQuery = null; foreach (SearchTerm entry in SearchTermFields) { if (entry == null) { continue; } if (entry.InArea != null && areaQuery == null) { IPoint p = SpatialContext.MakePoint(entry.InArea.Center.Latitude, entry.InArea.Center.Longitude); var circle = SpatialContext.MakeCircle(entry.InArea.Center.Latitude, entry.InArea.Center.Longitude, DistanceUtils.Dist2Degrees(entry.InArea.Radius, DistanceUtils.EARTH_EQUATORIAL_RADIUS_KM)); descriptor.SpatialArguments = new SpatialArgs(SpatialOperation.IsWithin, circle); descriptor.Filter = spatialStrategy.MakeFilter(descriptor.SpatialArguments); descriptor.InArea = true; areaQuery = ((PointVectorStrategy)spatialStrategy).MakeQueryDistanceScore(descriptor.SpatialArguments); } else if (entry.SearchingOption == SearchFieldOption.INTRANGE) { NumericRangeQuery <int> nq = NumericRangeQuery.NewInt32Range(entry.Field, entry.FromAsInt, entry.ToAsInt, true, true); query.Add(nq, entry.TermOccur); } else if (entry.SearchingOption == SearchFieldOption.DOUBLERANGE || entry.SearchingOption == SearchFieldOption.DECIMALRANGE) { NumericRangeQuery <double> nq = NumericRangeQuery.NewDoubleRange(entry.Field, entry.FromAsDouble, entry.ToAsDouble, true, true); query.Add(nq, entry.TermOccur); } //else if (entry.SearchingOption == SearchFieldOption.DECIMALRANGE) //{ // TermRangeQuery nq = TermRangeQuery.NewStringRange(entry.Field, entry.FromAsDecimal, entry.ToAsDecimal, true, true); // query.Add(nq, entry.TermOccur); //} else if (entry.SearchingOption == SearchFieldOption.LIKE) { QueryParser parser = new QueryParser(wings.IndexVersion, entry.Field, Analyzer); Query pquery = WildparseQuery(wings.Transformation.Transform(entry.Term), parser); query.Add(pquery, entry.TermOccur); } else if (entry.SearchingOption == SearchFieldOption.EXACT) { var exactQuery = new TermQuery(new Term(entry.Field, QueryParser.Escape(entry.Term.Trim()))); query.Add(exactQuery, entry.TermOccur); } else if (entry.SearchingOption == SearchFieldOption.FUZZY) { QueryParser parser = new QueryParser(wings.IndexVersion, entry.Field, Analyzer); Query pquery = FuzzyparseQuery(wings.Transformation.Transform(entry.Term), parser); query.Add(pquery, entry.TermOccur); } else { QueryParser parser = new QueryParser(wings.IndexVersion, entry.Field, Analyzer); Query pquery = ParseQuery(entry.Term, parser); query.Add(pquery, entry.TermOccur); } } if (areaQuery != null) { BooleanQuery areaQueries = new BooleanQuery { { query, Occur.MUST }, { areaQuery, Occur.MUST } }; descriptor.Query = areaQueries; } else { descriptor.Query = query; } return(descriptor); }