Geospatial Indexing with a simple key first

和自甴很熟 提交于 2019-12-07 14:24:52

问题


After reading about MongoDB and Geospatial Indexing

I was amazed that it did not support compound keys not starting with the 2d index.

I dont know if I would gain anything on it, but right now the mssql solution is just as slow/fast.

SELECT TOP 30 * FROM Villages WHERE SID = 10 ORDER BY (math to calc radius from the center point)

This works, but is slow because it not smart enough to use a index so it has to calc the radius for all villages with that SID.

So in Mongo I wanted to create an index like: {sid: 1, loc: "2d"} so I could filter out alot from the start.

I'm not sure there are any solutions for this. I thought about creating a collection for each sid since they don't share any information. But what are the disadvantages of this? Or is this how people do it ?

Update

The maps are flat: 800, 800 to -800,-800, villages are places from the center of the map and out. There are about 300 different maps which are not related, so they could be in diff collections, but not sure about the overhead.

If more information is need, please let me know.

What I have tried

> var res = db.Villages.find({sid: 464})
> db.Villages.find({loc: {$near: [50, 50]}, sid: {$in: res}})
error: { "$err" : "invalid query", "code" : 12580 }
>

Also tried this

db.Villages.find({loc: {$near: [50, 50]}, sid: {$in: db.Villages.find({sid: 464}, {sid: 1})}})
error: { "$err" : "invalid query", "code" : 12580 }

I'm not really sure what I'm doing wrong, but its probably somthing about the syntax. Confused here.


回答1:


As you stated already Mongodb cannot accept location as secondary key in geo index. 2d has to be first in index. So you are out of luck here in changing indexing patterns here.

But there is a workaround, instead the compound geo index you can create two separate indexes on sid and one compound index with loc and sid

  db.your_collection.ensureIndex({sid : 1})
  db.your_collection.ensureIndex({loc : '2d',sid:1})

or two separate indexes on sid and loc

  db.your_collection.ensureIndex({sid : 1})
  db.your_collection.ensureIndex({loc : '2d'})

(am not sure which of the above one is efficient, you can try it yourself)

and you can make two different queries to get the results filterd by sid first and the location next, kinda like this

  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}})  


来源:https://stackoverflow.com/questions/7986027/geospatial-indexing-with-a-simple-key-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!