6

次のようなドキュメントを含むMongoDBコレクションに基づいて、部分母集団の「ヒートマップ」を含むマップベースの視覚化を開発しようとしています:

{
    "PlaceName" : "Boston",
    "Location" : {
        "type" : "Point",
        "coordinates" : [ 42.358056, -71.063611 ]
    },
    "Subpopulations": {
        "Age": { 
                "0_4" : 37122,
                "6_11" : 33167,
                "12_17" : 35464,
                "18_24" : 130885,
                "25_34" : 127058,
                "34_44" : 79092,
                "45_54" : 72076,
                "55_64" : 59766,
                "65_74" : 33997,
                "75_84" : 20219,
                "85_" : 9057
        }
    }
}

データベースには何十万もの個別の場所があります。それらは重複しませ。つまり、"New York City" と "Manhattan" の 2 つの個別のエントリはありません。

目標は、Leaflet.js といくつかのプラグインを使用して、このデータのさまざまな視覚化をレンダリングすることです。Leaflet は、クライアント側でデータをクラスタリングするのに非常に優れています。したがって、密度値を含む 1000 の場所を渡すと、個々の値をすべて処理するだけで、関連する領域のヒート マップをレンダリングできます。

問題は、マップをズームアウトして全世界を表示するとします。そのすべてのデータをクライアントに送信し、スムーズな視覚化を行うのに十分な速さでその情報を処理させることは、不可能ではないにしても、非常に非効率的です。

したがって、私がする必要があるのは、サーバー側のデータを自動的にクラスター化することです。これは、MongoDB クエリで実行できることを望んでいます。ジオハッシュは、どのポイントがどのクラスターに属しているかを判断するための良い出発点である可能性があることを読んだことがありますが、誰かが以前にこれとまったく同じことを行ったことがあると確信しており、それよりも優れた洞察を持っている可能性があります. 理想的には、次のようなクエリを node.js スクリプトに送信したいと考えています。

http://myserver.com/popdata?top=42.48&left=-80.57&bottom=37.42&right=-62.55&stat=Age&value=6_11

これにより、返されるデータポイントの最大数、またはそれらの線に沿った何かが与えられた場合、その指定された地理的領域内にある個々のポイントの数に基づいて、クラスタリングをどの程度細かくする必要があるかが決まります。次のようなデータが返されます。

[
    { "clusterlocation": [ 42.304, -72.622 ], "total_age_6_11": 59042 },
    { "clusterlocation": [ 36.255, -64.124 ], "total_age_6_11": 7941 },
    { "clusterlocation": [ 40.425, -70.693 ], "total_age_6_11": 90257 },
    { "clusterlocation": [ 39.773, -67.992 ], "total_age_6_11": 102752 },
    ...
]

...ここで、「clusterlocation」はクラスター内のドキュメントのすべての場所の平均のようなものであり、「total_age_6_11」は「Subpopulations.Age.6_11」に対するこれらのドキュメントの値の合計です。

これは純粋にMongoクエリでできることですか? それをうまく行うための「試行錯誤された」方法はありますか?

4

1 に答える 1

4

このクエリを実行時に行ったとしても、優れたユーザー インターフェイスと見なされるには非効率的で高速ではありません。特定のサイズのクラスターを事前に生成し、元のドキュメントと共に現在のコレクションに保存しておくことをお勧めします。方法は次のとおりです。

  • 各ドキュメントには追加のフィールド ( geolevel と呼びましょう) が格納されます。これは、そのエンティティがどれほど小さいか大きいかを示します。ベース ドキュメントには geolevel=1 が含まれます。

    {
        "PlaceName" : "Boston",
        "Location" : {
            "type" : "Point",
            "coordinates" : [ 42.358056, -71.063611 ]
        },
        "Subpopulations": {
            "Age": { 
                    "0_4" : 37122,
                    "6_11" : 33167,
                    "12_17" : 35464,
                    "18_24" : 130885,
                    "25_34" : 127058,
                    "34_44" : 79092,
                    "45_54" : 72076,
                    "55_64" : 59766,
                    "65_74" : 33997,
                    "75_84" : 20219,
                    "85_" : 9057
            }
        },
        "geolevel":1  // added geolevel
    }
    
    • データベースで処理を実行して、クラスターや複数レベルの同様のドキュメントを事前に生成できます。たとえば、geolevel:2 は半径 250km 以内のいくつかの都市のクラスターになり、geolevel:3 は geolevel:2 クラスターのクラスターになります。

    • memberids各クラスターに子の ID を格納するようなフィールドを格納することもできます。これは、エンティティが 2 つの隣接するクラスターに入らないようにするために必要な場合があります。隣接するクラスターのいずれかに割り当てることができ、視覚化は引き続き正常に機能します。geolevel:2 クラスター ドキュメントは次のようになります。

       {
          "PlaceName" : "cluster_sdfs34535",  // The id can be generated from hash like sha of a list of all children ids.
          "Location" : {  // center of the cluster
              "type" : "Point",
              "coordinates" : [ 42.358056, -71.063611 ]
          },
          "Subpopulations": { // total population of the cluster
              "Age": { 
                      "0_4" : 371220,
                      "6_11" : 331670,
                      "12_17" : 354640,
                      "18_24" : 1308850,
                      "25_34" : 1270580,
                      "34_44" : 790920,
                      "45_54" : 720760,
                      "55_64" : 597660,
                      "65_74" : 339970,
                      "75_84" : 202190,
                      "85_" : 90570
              }
          },
          "geolevel":2 ,
          "childs":[4,5,6,7] // ids of child documents
      }
      
    • ここで、ビジュアライゼーション アプリはズームレベルからジオレベルへのマッピングを行う必要があり、それに基づいてドキュメントを選択します。都市レベルの視覚化の場合、geolevel:1 ドキュメントを照会できます。州や国などにズームアウトすると、geolevel を 2、3 に上げることができます...
于 2016-04-21T06:38:15.463 に答える