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}    

次の2つのインデックスを試しています

  • ロケーションのみ:db.action.ensureIndex({"location":"2d"})
  • LocationPlusTime: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"
}

与えられた

  • ジオサーチはすべてのタイプのドキュメントをカバーします
  • ジオサーチは、NO Location と WITH Location のドキュメントを約 60:40 の比率でカバーします。

私の質問は

  • 2番目の説明計画で isMultiKey="false" の理由を説明できる人はいますか?
  • 2番目の説明計画でより多くの収量がある理由を誰か説明できますか?

私の推理的な考えは

  • 場所が 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") 
}

更新 ジオクエリ 次のように なります

さまざまな理由から、約 250,000 のドキュメントがポイント 0.0 の DB に存在します。

4

1 に答える 1

2

これで数日間遊んで、探していた結果が得られました。

まず、「PLAY」以外のアクション タイプにはロケーションを指定できないため、追加のクエリ パラメータ「actionType==PLAY」は不要で削除されました。すぐに、「time-reverse-b-tree」カーソルから「Geobrowse-polygon」カーソルに切り替えたところ、私のテストでは、検索の待ち時間が 10 倍改善されました。

次に、Derick の提案に従って 2dsphere を再検討しました。ここでもまた、約 5 の遅延が改善されました。全体的に、マップ検索のユーザー エクスペリエンスが大幅に向上しました。

1つの改良点が残っています。数日間プレイされていない地域でのクエリは、一般的にレイテンシが増加しています。これは、クエリが「何らかの遊び」を見つけるまで時間をさかのぼって調べるためです。必要に応じて、時間範囲ガードを追加して、これらのクエリの検索スペースを設定された日数に制限します。

ヒントをありがとうデリック。

于 2013-08-23T12:42:37.373 に答える