2

我有一個包含這樣的文檔集合:

{ 
    "_id" : "cysMrqjootq6YS6WP", 
    「profile」 : { 
     …… 
     "deliveryDistance」 : 20, 
     "address" : { 
      "loc" : { 
       "type" : "Point", 
       "coordinates" : [ 
        —2.120361, 
        52.536273 
       ] 
      }  } 
    } 
} 

而且我有一個GeoJSON的點,如:

var referencePoint= { 
       "type" : "Point", 
       "coordinates" : [ 
        —2.120361, 
        52.536273 
       ] 
      } 

我使用Meteor.js,Node.js的和MongoDB。我想創建一個查詢,其中此點的maxDistance是每個文檔的deliveryDistance屬性到我的集合

如果maxDistance是一個固定值,查詢將是:

myCollection.find({ 
    「profile.address.loc":{ 
     "$nearSphere": { 
     "$geometry": referencePoint, 
     "$maxDistance": 20000 //for 20Kms 
     } 
    } 
    }) 

但這種情況並非如此。對於每個文檔,maxDistance必須是「profile.deliveryDistance」的值。如何在此查詢中將文檔中的此值用作maxDistance?可能嗎?如果沒有,還有其他想法?

回答

3

不能在.find()查詢中引用的文檔的現有特性,並且至少不能內的$near$nearSphere操作。

相反,這裏的方法是使用聚合框架和$geoNear。這使您可以計算與查詢點的距離,然後比較是否在文檔中的「deliveryDistance」內。

因此,對於流星,你可能是最好關閉安裝meteorhacks aggregate包,然後做這樣的事情:

Meteor.publish("aggResults",function(referencePoint) { 
    var self = this; 

    var results = myCollection.aggregate([ 
     { "$geoNear": { 
      "near": referencePoint, 
      "distanceField": "distance", 
      "spherical": true 
     }}, 
     { "$redact": { 
      "$cond": { 
       "if": { "$lt": [ "$distance", "$profile.deliveryDistance" ] }, 
       "then": "$$KEEP", 
       "else": "$$PRUNE" 
      } 
     }} 
    ]); 

    _.each(results,function(result) { 
     self.added("client_collection_name",result._id, { 
      "profile": result.profile, 
      "distance": result.distance   
     }); 
    }); 
    self.ready(); 
}) 

如果您的MongoDB服務器低於2.6版本(必須是至少2.4地理空間查詢),那麼你可以使用$project$match代替$redact過濾掉不屬於「deliveryDistance」中的文件:

var results = myCollection.aggregate([ 
     { "$geoNear": { 
      "near": referencePoint, 
      "distanceField": "distance", 
      "spherical": true 
     }}, 
     { "$project": { 
      "profile": 1, 
      "distance": 1, 
      "within": { "$lt": [ "$distance", "$profile.distance" ] } 
     }}, 
     { "$match": { "within": true } } 
    ]); 

但這是基本的情況,您可以向服務器提供工具來計算距離比較,然後返回任何這些文檔。

聚合輸出的包裝真的取決於在應用程序中使用數據對您來說很重要。這只是將輸出放入客戶端可尋址集合中的一個示例。

當然你也可以挖掘驅動程序的內部來調用.aggregate()shown here,但它可能沒有使用上述流星包那麼靈活。

+1

啊確定,聚合。非常感謝 :) –

相關問題