阅读有关MongoDB和Geospatial Indexing
的内容后我很惊讶它不支持不以2d索引开头的复合键。
我不知道我是否会获得任何东西,但是现在mssql解决方案同样慢/快。
SELECT TOP 30 * FROM Villages WHERE SID = 10 ORDER BY (math to calc radius from the center point)
这很有效,但速度很慢,因为它不够聪明,无法使用索引,因此必须使用该SID计算所有村庄的半径。
所以在Mongo中我想创建一个像{sid: 1, loc: "2d"}
这样的索引,所以我可以从一开始就过滤掉。
我不确定是否有任何解决方案。我考虑过为每个sid
创建一个集合,因为它们不共享任何信息。但这有什么缺点呢?或者这是人们如何做到的?
更新
地图是平的:800,800到-800,-800,村庄是从地图中心出来的地方。有大约300个不相关的不同地图,因此它们可以在差异集合中,但不确定开销。
如果需要更多信息,请告诉我。
我尝试了什么
> var res = db.Villages.find({sid: 464})
> db.Villages.find({loc: {$near: [50, 50]}, sid: {$in: res}})
error: { "$err" : "invalid query", "code" : 12580 }
>
也尝试了这个
db.Villages.find({loc: {$near: [50, 50]}, sid: {$in: db.Villages.find({sid: 464}, {sid: 1})}})
error: { "$err" : "invalid query", "code" : 12580 }
我不确定我做错了什么,但它可能与语法有关。在这里感到困惑。
答案 0 :(得分:2)
正如您所说,Mongodb无法接受位置作为地理索引中的辅助键。 2d必须是索引中的第一个。所以你在这里改变索引模式是不走运的。
但是有一个解决方法,相反,复合地理索引可以在sid上创建两个单独的索引,一个复合索引使用loc和sid
db.your_collection.ensureIndex({sid : 1})
db.your_collection.ensureIndex({loc : '2d',sid:1})
或sid和loc上的两个单独索引
db.your_collection.ensureIndex({sid : 1})
db.your_collection.ensureIndex({loc : '2d'})
(我不确定上述哪一个是有效的,你可以自己尝试一下)
并且您可以进行两个不同的查询,以便首先通过sid过滤结果,然后是下一个位置,有点像这样
res = db.your_collection.find({sid:10})
//get all the ids from the res (res_ids)
//and query by location using the ids
db.your_collection.find({loc:{ $near : [50,50] } ,sid : {$in : res_ids}})