我正在收集如下文件:
{
"_id" : ObjectId("5bc15f23d672e9086ca4fbac"),
"Location" : {
"GeoJson" : {
"type" : "Point",
"coordinates" : [14.4199254356, 50.0700249768]
}
}
我创建了如下索引
{ Location.GeoJson2dsphere : "2dsphere" }
现在当我使用$polygon
进行搜索时出现了问题,我得到了结果,但是查询未使用索引,因此速度很慢。这是查询
.find({"Location.GeoJson" : {
"$geoWithin" : {
"$polygon" : [
[14.4182910543168, 50.0891393887804],
[14.4491901021683, 50.0891393887804],
[14.4491901021683, 50.0671069088523],
[14.4182910543168, 50.0671069088523]
]
}
}
})
但是当我改用$ Geometry时,它使用的是索引。
.find({"Location.GeoJson" : {
"$geoWithin" :
{"$geometry" :
{"type" : "Polygon",
"coordinates" : [[
[14.4182910543168, 50.0891393887804],
[14.4491901021683, 50.0891393887804],
[14.4491901021683, 50.0671069088523],
[14.4182910543168, 50.0671069088523],
[14.4182910543168, 50.0891393887804]
]]
}}
}})
是否有任何原因导致第一个查询不使用索引? Mongo手册对此没有说什么。 您能指出我,使用$ polygon搜索索引该怎么做,还是我需要重写我应用程序中的所有查询才能使用$ geometry。我正在使用C#驱动程序,其语法如下所示:
Builders<Offer>.Filter.GeoWithinPolygon(a => a.Location.GeoJson, polygon);
但是,这是第一个查询,它不使用索引。
答案 0 :(得分:1)
我不为mongo工作,所以不会冒险猜测为什么(除了旧数据模型还是新数据模型)使新人感到困惑,但这是方法 mongo区分 infinite-flat-2d ($多边形查询)索引和 球形 索引( $ geometry查询)
传递 $ polygon 会针对旧版2d索引,而 $ geometry 会针对2d球形索引。 Mongo将这些查询分为两种不同的对象类型
此处:https://github.com/mongodb/mongo/blob/master/src/mongo/db/geo/geoparser.cpp#L785-L790
Mongo确实说只能通过 $ geometry 查询(不是传统的 $ polygon 查询)只能访问2dsphere索引
>此处:https://docs.mongodb.com/manual/tutorial/query-a-2dsphere-index/
如您所述: Mongo非常有帮助,即使您不匹配查询,它仍然可以返回数据。
为什么 $ polygon 甚至不再是东西?
对于那些希望在无限的平面上使用2d索引的人,Mongo继续支持非球形2d索引。也许是用于视频游戏,或者用于无限平坦的平面足以避免浮点数学运算(以及相关的舍入问题)的任何用途
此处描述:https://docs.mongodb.com/manual/tutorial/query-a-2d-index/
答案 1 :(得分:0)
好,我只是在C#中添加aswer。
新查询为:
GeoJsonPolygon<GeoJson2DCoordinates> polygon;
var filter = Builders<Offer>.Filter.GeoWithin(a => a.Location.GeoJson, polygon);
还有我的矩形帮助类。ToGeoJsonPolygon():
public class Rectangle
{
public double StartX { get; set; }
public double StartY { get; set; }
public double EndX { get; set; }
public double EndY { get; set; }
public double[,] ToCoordinates()
{
var retval = new double[4, 2];
retval[0, 0] = this.StartX;
retval[0, 1] = this.StartY;
retval[1, 0] = this.EndX;
retval[1, 1] = this.StartY;
retval[2, 0] = this.EndX;
retval[2, 1] = this.EndY;
retval[3, 0] = this.StartX;
retval[3, 1] = this.EndY;
return retval;
}
public GeoJsonPolygon<GeoJson2DCoordinates> ToGeoJsonPolygon()
{
return GeoJson.Polygon(
GeoJson.Position(StartX, StartY),
GeoJson.Position(EndX, StartY),
GeoJson.Position(EndX, EndY),
GeoJson.Position(StartX, EndY),
GeoJson.Position(StartX, StartY));
}
}