我的lucene索引的纬度和经度字段索引如下:
doc.Add(new Field("latitude", latitude.ToString() , Field.Store.YES, Field.Index.UN_TOKENIZED));
doc.Add(new Field("longitude", longitude.ToString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
我想从这个索引中检索一组文档,其lat和long值在给定范围内。
如您所知,Lat和long可能是负值。如何在Lucene中正确存储带符号的十进制数? 下面提到的方法是否会给出正确的结果,还是有其他方法可以做到这一点?
Term lowerLatitude = new Term("latitude", bounds.South.ToString() );
Term upperLatitude = new Term("latitude", bounds.North.ToString());
RangeQuery latitudeRangeQuery = new RangeQuery(lowerLatitude, upperLatitude, true);
findLocationQuery.Add(latitudeRangeQuery, BooleanClause.Occur.SHOULD);
Term lowerLongitude = new Term("longitude", bounds.West.ToString());
Term upperLongitude = new Term("longitude", bounds.East.ToString());
RangeQuery longitudeRangeQuery = new RangeQuery(lowerLongitude, upperLongitude, true);
findLocationQuery.Add(longitudeRangeQuery, BooleanClause.Occur.SHOULD);
另外,我想知道Lucene的ConstantScoreRangeQuery如何比RangeQuery类更好。
在此背景下面临另一个问题: 我在以下3个城市的索引中有一个文件:
Lyons,IL
Oak Brook,IL
加利福尼亚州旧金山
如果我输入“Lyons,IL”,则会出现此记录。 但如果我把旧金山,加州作为输入,那么它就不会。
但是,如果我按如下方式存储此文档的城市:
旧金山,加利福尼亚州
Lyons,IL
Oak Brook,IL
当我将旧金山,CA作为输入时,此记录会显示在搜索结果中。
我想要的是,如果我在输入中键入3个城市中的任何一个,我应该在搜索结果中获取此文档。
请帮助我实现这一目标。
感谢。
答案 0 :(得分:3)
根据skaffman的建议,您可以使用所有热门地图应用使用的相同tile coordinate system。根据您的需要选择任何缩放级别,并且不要忘记使用前导零填充。
关于RangeQuery,它比ConstantScoreRangeQuery慢,并且限制了值的范围。
关于城邦问题,我们只能推测。但首先要检查的是索引条款和解析后的查询是你期望的。
答案 1 :(得分:1)
我认为最好的方法是按照上一篇文章的建议转换/标准化坐标。这个article就是这样做的。它实际上是非常好的面向对象的代码。
关于你的第二个问题。我会假设你有某种分析器问题。您使用相同的Analyzer进行索引和查询吗?你使用哪些标记器?
我建议使用Luke检查生成的索引,以查看实际可搜索的令牌。
- 哈迪
答案 2 :(得分:0)
此处的一个选项是将坐标转换为没有负数的系统。例如,我对英国的谷歌地图webapp有类似的问题,我将Lucene的UK Easting / Northings(范围从0到7位)字段与lat / long值一起存储。通过用左填充的零格式化这些东/北,我可以进行lucene范围查询。
美国是否有类似的坐标系?