예제 #1
0
 public DistranceCustomScoreProvider(IndexReader reader, SpatialContext ctx, Point origin, double distance) : base(reader)
 {
     _reader   = reader;
     _ctx      = ctx;
     _origin   = origin;
     _distance = distance;
     this._distanceCalculator = new CustomDistanceCalculator();
 }
예제 #2
0
        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);
                    }
                }
        }
예제 #3
0
        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);
                    }
                }
        }