5

lucene.net インデックスの緯度と経度の値を使用して、単一のポイントからの距離に基づいて順序付けられた結果のセットを返す経験がある人はいますか?

Lucene.Net.Spatial ライブラリは、これに役立ちますか?

4

1 に答える 1

4

パーティーに少し遅れましたが、そうです、Spatialライブラリはこれから始める場所です。その背後にある基本は次のとおりです。

1)ドキュメントにLatフィールドとLongフィールドを追加します

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で見ることができます

于 2013-01-28T13:43:48.967 に答える