优化复合Mongo地理空间索引

时间:2013-07-24 10:36:07

标签: mongodb optimization indexing geo

我有一个看起来像这样的MongoDB $within

db.action.find( { $and : [
    { actionType : "PLAY" },
    { 
        location : { 
            $within : { 
                $polygon : [ [ 0.0, 0.1 ], [ 0.0, 0.2 ] .. [ a.b, c.d ] ]
            } 
        }
    }
] } ).sort( { time : -1 } ).limit(50)

关于行动收集文件

  • 有5个actionTypes
  • 行动文件可能或可能没有PLAY行动的比率约为70:30的位置
  • 否则没有位置
  • 行动文件总是有时间

该集合包含以下索引

# I am interested recent actions 
db.action.ensureIndex({"time": -1}          

# I am interested in recent actions by a specific user
db.action.ensureIndex({"userId" : 1}, "time" -1}    

# I am interested in recent actions that relate to a unique song id
db.action.ensureIndex({"songId" : 1}, "time" -1}    

我正在尝试以下两个索引

  • LocationOnly:db.action.ensureIndex({"location":"2d"})
  • LocationPlusTime:db.action.ensureIndex({"location":"2d"}, { "time": -1})

每个索引的相同查询解释如下:

LocationOnly

{
    "cursor":"BasicCursor",
    "isMultiKey":false,
    "n":50,
    "nscannedObjects":91076,
    "nscanned":91076,
    "nscannedObjectsAllPlans":273229,
    "nscannedAllPlans":273229,
    "scanAndOrder":true,
    "indexOnly":false,
    "nYields":1,
    "nChunkSkips":0,
    "millis":1090,
    "indexBounds":{},
    "server":"xxxx"
}

LocationPlusTime

{
    "cursor":"BasicCursor",
    "isMultiKey":false,
    "n":50,
    "nscannedObjects":91224,
    "nscanned":91224,
    "nscannedObjectsAllPlans":273673,
    "nscannedAllPlans":273673,
    "scanAndOrder":true,
    "indexOnly":false,
    "nYields":44,
    "nChunkSkips":0,
    "millis":1156,
    "indexBounds":{},
    "server":"xxxxx"
}

给出

  • 地理搜索将涵盖所有类型的文档
  • geosearch将覆盖NO位置和WITH Location的文档,比例大约为60:40

我的问题是

  • 任何人都可以在第二个解释计划中解释为什么isMultiKey =“false”?
  • 有人可以解释为什么第二次解释计划会有更多的收益吗?

我的思辨是

  • NULL定位的可能性正在降低其有效性 地理空间索引。
  • GeoSpatial品种的复合指数不如标准化合物指数那么强大。

更新 示例文档如下所示。

{ "_id" : "adba1154f1f3d4ddfafbff9bb3ae98f2a50e76ffc74a38bae1c44d251db315d25c99e7a1b4a8acb13d11bcd582b9843e335006a5be1d3ac8a502a0a205c0c527", 
  "_class" : "ie.soundwave.backstage.model.action.Action", 
  "time" : ISODate("2013-04-18T10:11:57Z"),
  "actionType" : "PLAY",
  "location" : { "lon" : -6.412839696767714, "lat" : 53.27401934563561 },
  "song" : { "_id" : "82e08446c87d21b032ccaee93109d6be", 
             "title" : "Motion Sickness", "album" : "In Our Heads", "artist" : "Hot Chip"
           }, 
  "userId" : "51309ed6e4b0e1fb33d882eb", "createTime" : ISODate("2013-04-18T10:12:59.127Z") 
}

更新 地理查询看起来像这样 https://www.google.com/maps/ms?msid=214949566612971430368.0004e267780661744eb95&msa=0&ll=-0.01133,-0.019226&spn=0.14471,0.264187

由于各种原因,我们的数据库中存在大约250,000个文档,点0.0

1 个答案:

答案 0 :(得分:2)

我玩了好几天,得到了我想要的结果。

首先,假设“PLAY”以外的动作类型不能有位置,则不需要附加查询参数“actionType == PLAY”并将其删除。直接我从“time-reverse-b-tree”光标翻转到“Geobrowse-polygon”,我的测试搜索延迟提高了10个。

接下来,我按照Derick的建议再次访问了2dsphere。再次延迟提高了大约5个。总体而言,实现了更好的地图搜索用户体验。

我还有一个改进。在几天没有播放的区域中的查询通常会增加延迟。这是由于查询及时回顾,直到找到“一些游戏”。如有必要,我将添加时间范围保护,以将这些查询的搜索空间限制为设定的天数。

感谢Derick的提示。