public DistranceCustomScoreProvider(IndexReader reader, SpatialContext ctx, Point origin, double distance) : base(reader) { _reader = reader; _ctx = ctx; _origin = origin; _distance = distance; this._distanceCalculator = new CustomDistanceCalculator(); }
public async Task <List <NearestPlace> > GetNearest(string type, double lat, double lng, int distance) { var index = await CreateIndex(await new GooglePlacesService().GetDataAsync()); using (var reader = IndexReader.Open(index, true)) using (var searcher = new IndexSearcher(reader)) { using (var analyzer = new StandardAnalyzer(LuceneNet.Util.Version.LUCENE_30)) { var ctx = SpatialContext.GEO; var origin = ctx.MakePoint(lat, lng); var distanceCalculator = new CustomDistanceCalculator(); var typesQueryParser = new QueryParser(LuceneNet.Util.Version.LUCENE_30, Schema.Types, analyzer); var typesQuery = typesQueryParser.Parse(type); var distanceQuery = new DistanceCustomScoreQuery(typesQuery, ctx, origin, distance); var collector = TopScoreDocCollector.Create(1000, true); var posCollector = new PositiveScoresOnlyCollector(collector); searcher.Search(distanceQuery, posCollector); var matches = collector.TopDocs(); var result = new List <NearestPlace>(); foreach (var match in matches.ScoreDocs) { var id = match.Doc; var doc = searcher.Doc(id); var nearestPlace = DocToNearestPlace(doc); nearestPlace.Distance = distanceCalculator.Calculate(ctx, doc, origin, true); result.Add(nearestPlace); } return(result); } } }
public async Task <List <SearchPlace> > Search(string queryString, double lat, double lng) { var index = await CreateIndex(await new GooglePlacesService().GetDataAsync()); using (var reader = IndexReader.Open(index, true)) using (var searcher = new IndexSearcher(reader)) { using (var analyzer = new StandardAnalyzer(LuceneNet.Util.Version.LUCENE_30)) { var ctx = SpatialContext.GEO; var origin = ctx.MakePoint(lat, lng); var distanceCalculator = new CustomDistanceCalculator(); var queryParser = new MultiFieldQueryParser(LuceneNet.Util.Version.LUCENE_30, new[] { Schema.Name, Schema.Vicinity }, analyzer); queryParser.DefaultOperator = QueryParser.Operator.OR; var query = queryParser.Parse(queryString); var collector = TopScoreDocCollector.Create(1000, true); var posCollector = new PositiveScoresOnlyCollector(collector); searcher.Search(query, posCollector); var matches = collector.TopDocs(); var result = new List <SearchPlace>(); foreach (var match in matches.ScoreDocs) { var id = match.Doc; var doc = searcher.Doc(id); var searchPlace = DocToSearchPlace(doc); searchPlace.Distance = distanceCalculator.Calculate(ctx, doc, origin, true); result.Add(searchPlace); } var map = new Dictionary <int, SearchPlace>(); for (int i = 0; i < matches.ScoreDocs.Length; i++) { map.Add(matches.ScoreDocs[i].Doc, result[i]); } var intermediate = map .Join(matches.ScoreDocs, left => left.Key, right => right.Doc, (left, right) => new { left, right }) .OrderByDescending(x => x.right.Score); var bothMatched = intermediate.Where(x => x.right.Score > 1); var oneMatched = intermediate.Where(x => x.right.Score < 1); result = new List <SearchPlace>(); result.AddRange(bothMatched .OrderBy(x => x.left.Value.Distance) .Select(x => x.left.Value) .ToList()); result.AddRange(oneMatched .OrderBy(x => x.left.Value.Distance) .Select(x => x.left.Value) .ToList()); return(result); } } }