sql >> データベース >  >> NoSQL >> MongoDB

$nearを使用してドキュメントに保存されている距離でドキュメントをフィルタリングする

    イベントデータを受け取り、手元に置いたときに、イベントデータに基づいて行動するようにすでに取り組んでいると仮定します(そうでない場合は、別の質問ですが、テーラブルカーソル )、次に、ユーザーにクエリを実行するためのデータを含むオブジェクトが必要です。

    したがって、これは $where<を使用したJavaScript評価には当てはまりません。 / code> $nearから返されたクエリデータにアクセスできないため とにかく操作。代わりに必要なのは、 $ geoNear > 集約フレームワークから。これにより、クエリから見つかった「距離」を予測し、後の段階で、公開されたイベントまで移動したい最大距離について、ユーザーが保存した値に対して結果を「フィルタリング」できるようになります。

    // Represent retrieved event data
    var eventData = {
      eventLocation: {
        latlong: [long,lat]
      }
    };
    
    // Find users near that event within their stored distance
    User.aggregate(
      [
        { "$geoNear": {
          "near": {
            "type": "Point",
            "coordinates": eventData.eventLocation.latlong
          },
          "distanceField": "eventDistance",
          "limit": 100000,
          "spherical": true
        }},
        { "$redact": {
          "$cond": {
            "if": { "$lt": [ "$eventDistance", "$maxDistance" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
          }
        }}
      ]
      function(err,results) {
        // Work with results in here
      }
    )
    

    ここで、返される数値に注意する必要があります。GeoJSONではなく「レガシー座標ペア」で格納しているように見えるため、この操作から返される距離はラジアンであり、標準の距離ではありません。したがって、ユーザーオブジェクトに「マイル」または「キロメートル」で格納していると仮定すると、「球面幾何学を使用して距離を計算する」 マニュアルに記載されているように。

    基本的には、地球の赤道半径で割る必要があります。保存したものと比較するために変換するには、3,963.2マイルまたは6,378.1キロメートルのいずれかです。

    別の方法は、代わりにGeoJSONに保存することです。ここでは、メートル単位で一貫した測定が行われます。

    「キロメートル」を「if」の線が次のようになると仮定します。

    "if": { "$lt": [
        "$eventDistance",
        { "$divide": [ "$maxDistance", 6,378.1 ] }
     ]},
    

    保存されたキロメートル値を、取得されたラジアン結果と確実に比較するため。

    もう1つ注意すべき点は、 $ geoNear デフォルトの「制限」は100件であるため、予想されるユーザーが一致する可能性がある数に「制限」引数を「ポンプアップ」する必要があります。非常に大規模なシステムのユーザーIDの「範囲リスト」でこれを実行することもできますが、1回の集計操作でメモリが許す限り大きくして、 allowDiskUse 必要に応じて。

    そのパラメータを調整しないと、最も近い100個の結果(デフォルト)のみが返されます。これは、最初にイベントの「近く」をフィルタリングする次の操作にさえ適さない可能性があります。ただし、常識を働かせてください。潜在的なユーザーを除外するための最大距離が確実にあり、それをクエリに追加することもできます。

    前述のように、ここでのポイントは比較のために距離を返すことなので、次の段階は $ redact イベントから返された距離に対してユーザー自身の「移動距離」値を適合させることができる操作。最終結果は、通知の対象となるイベントから自分の距離内にあるユーザーのみを提供します。

    それが論理です。ユーザーからイベントまでの距離を予測し、ユーザーが保存した値と比較して、ユーザーが移動する準備ができている距離を確認します。 JavaScriptはなく、JavaScriptを非常に高速にするすべてのネイティブ演算子。

    また、オプションと一般的な解説に記載されているように、正確な球面距離の計算には「2dsphere」インデックスを使用し、データベースオブジェクトの座標ストレージにはGeoJSONストレージに変換することをお勧めします。どちらも一般的な標準です。一貫した結果を生み出します。



    1. mongodbで削除されたスペースを自動圧縮しますか?

    2. MongoDBでの年および月ごとの集計

    3. 列挙型のマングースモデルのカスタムエラーメッセージ

    4. 配列の最初のアイテムを新しいフィールドに投影します(MongoDB集計)