2012-12-13 21 views
5

Czy ktokolwiek ma jakiekolwiek doświadczenie z posiadaniem wartości szerokości i długości geograficznej indeksu lucene.net, a następnie zwraca uporządkowany zestaw wyników na podstawie odległości od jednego punktu?Wyszukiwanie bliskości Lucene.net

Czy biblioteka Lucene.Net.Spatial w ogóle mi w tym pomoże?

+1

Dobre pytanie. Chciałbym również wiedzieć. –

Odpowiedz

4

Trochę spóźniony na imprezę, ale tak, biblioteka przestrzenna to miejsce, od którego należy zacząć. Podstawy za nim są:

1) Dodawanie pól Lat i długi do dokumentu

doc.Add(new Field("Latitude", 
        NumericUtils.DoubleToPrefixCoded(Latitude), 
        Field.Store.YES, Field.Index.NOT_ANALYZED)); 

doc.Add(new Field("Longitude", 
        NumericUtils.DoubleToPrefixCoded(Longitude), 
        Field.Store.YES, Field.Index.NOT_ANALYZED)); 

2) Utwórz plotery dla każdej kondygnacji szczegółowości że wyszukiwanie musi obsługiwać

IProjector projector = new SinusoidalProjector(); 
var ctp = new CartesianTierPlotter(0, projector, 
            Fields.LocationTierPrefix); 
StartTier = ctp.BestFit(MaxKms); 
EndTier = ctp.BestFit(MinKms); 

Plotters = new Dictionary<int, CartesianTierPlotter>(); 
for (var tier = StartTier; tier <= EndTier; tier++) 
{ 
    Plotters.Add(tier, new CartesianTierPlotter(tier, 
              projector, 
              Fields.LocationTierPrefix)); 
} 

3) Użyj plotery indeksować dokument dla każdej kondygnacji

private static void AddCartesianTiers(double latitude, 
             double longitude, 
             Document document) 
{ 
    for (var tier = StartTier; tier <= EndTier; tier++) 
    { 
     var ctp = Plotters[tier]; 
     var boxId = ctp.GetTierBoxId(latitude, longitude); 
     document.Add(new Field(ctp.GetTierFieldName(), 
         NumericUtils.DoubleToPrefixCoded(boxId), 
         Field.Store.YES, 
         Field.Index.NOT_ANALYZED_NO_NORMS)); 
    } 
} 

z listy Zindeksowany dokument można przenieść na tworzenie zapytania. Ten przykład używa ConstantScoreQuery ale można zamienić że się za wahały punktacji:

/* Builder allows us to build a polygon which we will use to limit 
* search scope on our cartesian tiers, this is like putting a grid 
* over a map */ 
var builder = new CartesianPolyFilterBuilder(Fields.LocationTierPrefix); 

/* Bounding area draws the polygon, this can be thought of as working 
* out which squares of the grid over a map to search */ 
var boundingArea = builder.GetBoundingArea(Latitude, 
       Longitude, 
       DistanceInKilometres * ProductSearchEngine.KmsToMiles); 

/* We refine, this is the equivalent of drawing a circle on the map, 
* within our grid squares, ignoring the parts the squares we are 
* searching that aren't within the circle - ignoring extraneous corners 
* and such */ 
var distFilter = new LatLongDistanceFilter(boundingArea, 
            DistanceInKilometres * KmsToMiles, 
            Latitude, 
            Longitude, 
            ProductSearchEngine.Fields.Latitude, 
            ProductSearchEngine.Fields.Longitude); 

/* We add a query stating we will only search against products that have 
* GeoCode information */ 
var query = new TermQuery(new Term(Fields.HasGeoCode, 
            FieldFlags.HasField)); 

/* Add our filter, this will stream through our results and 
* determine eligibility */ 
masterQuery.Add(new ConstantScoreQuery(distanceFilter), 
       BooleanClause.Occur.MUST); 

Wszystko to pochodzi z blogu Właśnie napisała natomiast patrząc na podobnym problemem. Możesz to zobaczyć pod http://www.leapinggorilla.com/Blog/Read/1005/spatial-search-in-lucenenet

+0

Dzięki za wspaniały przykład. Mam problem z częścią boundingArea ... coś jest nie tak, gdy tylko oferuje dokumenty, które są blisko siebie, ale daleko od współrzędnych, o które prosiłem, więc LatLongDistanceFilter sprawdza je i stwierdza, że ​​" jest zbyt daleko, więc żadne wyniki nie są zwracane. – Jarvis

+1

Dodałem kolejny przykład do naszego bloga (http://leapinggorilla.com/Blog/Read/1010/spatial-search-in-lucenenet---worked-example). Ma cały kod potrzebny do działania aplikacji demo, więc mam nadzieję, że ci pomożemy. – Wolfwyrd

Powiązane problemy