有没有人有 lucene.net 索引纬度和经度值的经验,然后根据与单点的距离返回一组有序的结果?
Lucene.Net.Spatial 库会帮我解决这个问题吗?
有没有人有 lucene.net 索引纬度和经度值的经验,然后根据与单点的距离返回一组有序的结果?
Lucene.Net.Spatial 库会帮我解决这个问题吗?
聚会有点晚了,但是是的,空间图书馆是从这里开始的地方。其背后的基础是:
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看到它