2012-12-13 33 views
5

有沒有人擁有lucene.net index經緯度值的經驗,然後根據距單點距離返回一組有序的結果?Lucene.net proximity搜索

Lucene.Net.Spatial庫對我有所幫助嗎?

+1

好問題。我也想知道。 –

回答

4

晚會有點晚,但是,空間圖書館是開始的地方。其背後的基礎是:

1)添加緯度和長域到您的文檔

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)創建粒度的每一層,你的搜索需要支持繪圖儀

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)使用您的繪圖儀爲您的文檔編制索引

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)); 
    } 
} 

隨着你的索引文件,你可以移動到建立一個查詢。本例中使用ConstantScoreQuery,但你可以換是出於對你的遠程評分:

/* 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); 

所有這一切都從一個博客帖子我只是寫,而在尋找類似的問題而採取的。你可以看到它在http://www.leapinggorilla.com/Blog/Read/1005/spatial-search-in-lucenenet

+0

感謝您的好例子。我遇到了boundingArea部分的問題......只是提供的文檔相互之間距離很近,但距離要求的座標很遠,所以LatLongDistanceFilter檢查它們並發現它們'離得太遠,所以沒有結果返回。 – Jarvis

+1

我在我們的博客中添加了另一個工作示例(http://leapinggorilla.com/Blog/Read/1010/spatial-search-in-lucenenet---worked-example)。這有你需要看到一個演示應用程序運行的所有代碼,所以應該有希望幫助你。 – Wolfwyrd