2012-10-15 30 views
5

मोंगो शैल में एक चौराहे या ओवरलैप क्वेरी कैसे करें - कौन से मंडल मेरे खोज क्षेत्र को ओवरलैप करते हैं? Within केवल केंद्र की स्थिति से संबंधित है लेकिन खोज के दायरे में अन्य मंडलियों के त्रिज्या शामिल नहीं है।केंद्रीय सर्कल के त्रिज्या से सभी ओवरलैपिंग सर्कल कैसे ढूंढें?

मोंगो:

रूबी:

# field :circle, type: Circle # eg. [ [ 30, 30 ], 10 ] 
field :radius, type: Integer 
field :location, :type => Array, :spatial => true 
spatial_index :location 

Places.within_circle(location: [ [ 30, 30 ], 10 ]) 

# {"$query"=>{"location"=>{"$within"=>{"$center"=>[[30, 30], 10]}}} 

मैं अतिरिक्त स्थान के साथ उदाहरण डेटा बनाया

# My bad conception: 
var search = [[30, 30], 10] 
db.places.find({circle : {"$within" : {"$center" : [search]}}}) 

अब मैं केंद्रीय बिंदु के भीतर ही इस हलकों प्राप्त कर सकते हैं चक्र के खोजा क्षेत्र में है (विशेष इंडेक्स) और इसके बजाय त्रिज्या सर्कल क्योंकि मंडल mongodb geo अनुक्रमणिका द्वारा समर्थित नहीं है:

{ "_id" : 1, "name" : "a", "circle" : [ [ 5, 5 ], 40 ], "latlng" : [ 5, 5 ], "radius" : 40 } 
{ "_id" : 2, "name" : "b", "circle" : [ [ 10, 10 ], 5 ], "latlng" : [ 10, 10 ], "radius" : 5 } 
{ "_id" : 3, "name" : "c", "circle" : [ [ 20, 20 ], 5 ], "latlng" : [ 20, 20 ], "radius" : 5 } 
{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50} 
{ "_id" : 5, "name" : "e", "circle" : [ [ 80, 80 ], 30 ], "latlng" : [ 80, 80 ], "radius" : 30} 
{ "_id" : 6, "name" : "f", "circle" : [ [ 80, 80 ], 20 ], "latlng" : [ 80, 80 ], "radius" : 20} 

वांछित क्वेरी परिणाम:

{ "_id" : 1, "name" : "a", "circle" : [ [ 5, 5 ], 40 ], "latlng" : [ 5, 5 ], "radius" : 40 } 
{ "_id" : 3, "name" : "c", "circle" : [ [ 20, 20 ], 5 ], "latlng" : [ 20, 20 ], "radius" : 5 } 
{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50} 
{ "_id" : 5, "name" : "e", "circle" : [ [ 80, 80 ], 30 ], "latlng" : [ 80, 80 ], "radius" : 30} 

नीचे समाधान मानता है कि मैं सभी पंक्तियां प्राप्त और फिर मेरी त्रिज्या पक्ष माणिक पर फ़िल्टर लेकिन यह केवल रिटर्न:

{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50} 
+0

मुझे लगता है कि आप वापस चाहते हैं "एक"

यहाँ एक काम के आसपास खोल में है कि गणना के आधार पर है , "सी और डी"। "ई" आपके सर्कल से ओवरलैप नहीं होता है। –

+0

मैं पहली बार जवाब देने पर अपना कोड नहीं देख सका। इसे जांच लिया और इसे अभी तय कर दिया। आप स्वयं देख सकते हैं। जैसा कि अस्या कामस्की ने कहा, आप केवल एक, सी और डी की उम्मीद करते हैं। अन्यथा जो जानकारी आपने हमें दी है वह गलत है। – oldergod

+0

असल में मैंने "ई" पर गलती की। दोनों समाधान अच्छे हैं, लेकिन अब मैं देखता हूं कि वर्तमान समय के लिए रूबी का उपयोग किया जाएगा। मुझे डर है कि रिकॉर्ड के बड़े आकार पर मेरा प्रोग्राम बहुत तेज़ काम नहीं कर सकता है, इसलिए मैंने मोंगो में दृष्टिकोण के बारे में भी पूछा। धन्यवाद! – roza

उत्तर

5

मैं परिचित नहीं हूँ mongodb के साथ, लेकिन मुझे लगता है कि [[x, y], r] मानों का अर्थ है

x: अक्ष x पर केंद्र का मान। वाई: धुरी वाई पर केंद्र का मूल्य। आर: सर्कल त्रिज्या।

(S.center और A.center) आप चक्र एस जो आपके खोज और एक यादृच्छिक चक्र ए तो फिर तुम दोनों मंडलियां 'केंद्र के बीच की दूरी calcule सकता है कहो और देखें कि क्या वह उन दोनों से हीन है मंडल त्रिज्या जोड़ा (एसआर + आर)।

def distance_between(a, b) 
    ((b.first - a.first)**2 + (b.last - a.last)**2)**0.5 
end 

elements = [{ _id: 1, name: "a", circle: [ [ 5, 5 ], 40 ] }, 
      { _id: 2, name: "b", circle: [ [ 10, 10 ], 5 ] }, 
      { _id: 3, name: "c", circle: [ [ 20, 20 ], 5 ] }, 
      { _id: 4, name: "d", circle: [ [ 30, 30 ], 50 ] }, 
      { _id: 5, name: "e", circle: [ [ 80, 80 ], 30 ] }, 
      { _id: 6, name: "f", circle: [ [ 80, 80 ], 20 ] }] 
search = [[30, 30], 10] 

elements.select do |elem| circle = elem[:circle] 
    distance_between(circle.first, search.first) <= circle.last + search.last 
end 

#{:_id=>1, :name=>"a", :circle=>[[5, 5], 40]} 
#{:_id=>3, :name=>"c", :circle=>[[20, 20], 5]} 
#{:_id=>4, :name=>"d", :circle=>[[30, 30], 50]} 
3

दुर्भाग्य से वर्तमान में मोंगो में कोई क्षमता सीधे अतिव्यापी वस्तुओं, वस्तुओं के भीतर केवल अंक के बारे में क्वेरी करने के लिए है।

@ oldergod का जवाब एल्गोरिदम का वर्णन करता है कि गणना करने के लिए कि दो मंडल ओवरलैप हैं या नहीं।

function distance(a, b) { 
    return Math.pow(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2), 0.5); 
} 

अपने नमूना डेटा पर संग्रह 'चक्र' में डाला:

> db.circle.find().forEach(
    function(c) { 
     if ((distance(c.latlng, search.latlng) < c.radius + search.radius)) 
      { 
       print(c.name); 
      } 
    }) 
a 
c 
d 
> 
+0

कृपया ध्यान दें कि 2 के रूप में।4 (मार्च 2013) $ geoIntersects ऑपरेटर GeoJSON और 2 डी स्पेयर इंडेक्स के लिए यह कार्यक्षमता प्रदान करने के लिए उपलब्ध है। –