1

我有一个$within如下所示的 MongoDB:

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 种动作类型
  • 对于 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}    

我正在尝试以下两个索引

  • 仅位置:db.action.ensureIndex({"location":"2d"})
  • 位置加时间:db.action.ensureIndex({"location":"2d"}, { "time": -1})

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

仅位置

{
    "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"
}

位置加时间

{
    "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"
}

给定

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

我的问题是

  • 谁能在第二个解释计划中解释为什么 isMultiKey="false" ?
  • 谁能解释为什么第二个解释计划有更多的收益?

我的推测是

  • NULL 位置可能会降低 GeoSpatial 索引的有效性。
  • 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 点

4

1 回答 1

2

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

首先,鉴于“PLAY”以外的动作类型不能有位置,附加的查询参数“actionType==PLAY”是不必要的并被删除。我立即从“time-reverse-b-tree”光标切换到“Geobrowse-polygon”,我的测试搜索延迟提高了 10 个数量级。

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

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

感谢德里克的提示。

于 2013-08-23T12:42:37.373 回答