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

$ boxとmongodbを使用してドキュメントを取得し、特定の座標点を持つ各レコードの距離フィールドを追加します

    これは機能するはずです:

    db.collection.aggregate([
       {
          "$match": {
             "location": {
                "$geoWithin": {
                   "$box": [
                      [0.024719919885622943, 51.54643953472475],
                      [-0.1589577534542408, 51.47239969138267]
                   ]
                }
             }
          }
       },
       { $set: { lon: -0.0649729793707321 } },
       { $set: { lat: 51.50160291888072 } },
       {
          $set: {
             distance: {
                $let: {
                   vars: {
                      dlon: { $degreesToRadians: { $subtract: [{ $arrayElemAt: ["$location.coordinates", 0] }, "$lon"] } },
                      dlat: { $degreesToRadians: { $subtract: [{ $arrayElemAt: ["$location.coordinates", 1] }, "$lat"] } },
                      lat1: { $degreesToRadians: { $arrayElemAt: ["$location.coordinates", 1] } },
                      lat2: { $degreesToRadians: "$lat" }
                   },
                   in: {
                      // Haversine formula: sin²(dLat / 2) + sin²(dLon / 2) * cos(lat1) * cos(lat2);
                      $add: [
                         { $pow: [{ $sin: { $divide: ["$$dlat", 2] } }, 2] },
                         { $multiply: [{ $pow: [{ $sin: { $divide: ["$$dlon", 2] } }, 2] }, { $cos: "$$lat1" }, { $cos: "$$lat2" }] }
                      ]
                   }
                }
             }
          }
       },
       {
          $set: {
             distance: {
                // Distance in Meters given by "6372.8 * 1000"
                $multiply: [6372.8, 1000, 2, { $asin: { $sqrt: "$distance" } }]
             }
          }
       },
    ])
    

    注、$box レガシー座標ペア にのみ使用されます 。適切なクエリ(つまり、2dsphereの適切な使用) index)$geometryを使用する必要があります :

    db.collection.createIndex({ location: "2dsphere" })
    db.collection.find(
       {
          "location": {
             "$geoWithin": {
                "$geometry": {
                   type: "Polygon",
                   coordinates: [[
                      [-0.1589577534542408, 51.47239969138267],
                      [-0.1589577534542408, 51.54643953472475],
                      [0.024719919885622943, 51.54643953472475],
                      [0.024719919885622943, 51.47239969138267],
                      [-0.1589577534542408, 51.47239969138267]
                   ]]
                }
             }
          }
       }
    ).explain().queryPlanner.winningPlan.inputStage.indexName
    
    --> location_2dsphere // which means index is used
    
    
    db.collection.find(
       {
          "location": {
             "$geoWithin": {
                "$box": [
                   [0.024719919885622943, 51.54643953472475],
                   [-0.1589577534542408, 51.47239969138267]
                ]
             }
          }
       }
    ).explain().queryPlanner.winningPlan.stage
    
    --> COLLSCAN // which means full collection scan
    

    またはレガシー座標の適切な使用:

    db.collection.createIndex({ "location.coordinates": "2d" })
    db.collection.find(
       {
          "location.coordinates": { // <- note this difference
             "$geoWithin": {
                "$box": [
                   [0.024719919885622943, 51.54643953472475],
                   [-0.1589577534542408, 51.47239969138267]
                ]
             }
          }
       }
    ).explain().queryPlanner.winningPlan.inputStage.indexName
    
    --> location.coordinates_2d
    



    1. PHPを使用してmongodbに日付とタイムスタンプを挿入および取得する

    2. 暗号化を使用してMongoDBデータを保護する方法

    3. MongoDB RubyDriver2.5.xレプリカセットのホスト名で大文字と小文字を区別する問題

    4. binairyやその他のデータを使用して画像を投稿する