2016-02-15 9 views
9

Postgres PostGIS ile Ruby On Rails üzerinde yapmaya çalışıyorum.raylar üzerinde sıralı bir listeden sayım alt sorgusuna göre sipariş ve gruplandırma nasıl

Gruplama yapmaya çalışıyorum ve sahip olduğum listenin bulunduğu şehre güveniyorum.

Koordinatlarıma en yakın noktaların bir listesini aldım (110.1862202 1.6031959).

Artık şehirlere göre gruplandırmak ve her şehirdeki öğe sayısını saymak istiyorum. Ancak, biçim doğrudur, ancak bir şekilde siparişini kaybetmiştir. Şehirlerin koordinatıma en yakın şekilde sıralanmasını istiyorum. Bütün nokta en yakın şehri almak ama şimdi en yakın sipariş değil.

sorgu sorun grubu ve saymak alt sorgu

scope :nearestcitysubquery, ->() { 
    from(Treasure.order("ST_Distance(treasures.location_point, 
     ST_GeographyFromText('SRID=4326;POINT(110.1862202 1.6031959)'))"), 
     "subquery_treasure_nearest").group("city").count 
    } 

asıl sonuç

=> {"Kuala Lumpur"=>1, "null"=>1, "Sungai Besar"=>1, "Sungai Udang"=>1, "Kuching"=>1} 

beklenen sonuç

=> {"Kuching"=>1, "Sungai Besar"=>1, "Sungai Udang"=>1, "Kuala Lumpur"=>1, "null"=>1} 

Benim sipariş sorgu doğru

işleri (Doğru) sipariş
Treasure.order("ST_Distance(treasures.location_point, 
     ST_GeographyFromText('SRID=4326;POINT(110.1862202 1.6031959)'))") 

sonuç

=> #<ActiveRecord::Relation [#<Treasure id: 5, user_id: 1, treasure_name: "Kucing", treasure_image: nil, description: "Kucing", hint: nil, location: "Jalan Ke Puncak Serapi", created_at: "2016-01-08 03:46:40", updated_at: "2016-01-08 03:46:40", treasure_id: "TRKKY", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942b71c8 "POINT (110.18 1.6)">, city: "Kuching", state: "Sarawak", country: "Malaysia", difficulty: 2, google_place_id: "ChIJZf_iRaYF-zERMH5qt30cJJw", size: 2>, #<Treasure id: 4, user_id: 1, treasure_name: "Lori", treasure_image: nil, description: "Lori", hint: nil, location: "Jalan Samsudin", created_at: "2016-01-08 03:45:26", updated_at: "2016-01-08 03:45:26", treasure_id: "T3UKD", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942bbd68 "POINT (102.14 2.27)">, city: "Sungai Udang", state: "Melaka", country: "Malaysia", difficulty: 2, google_place_id: "ChIJq6_zCZX50TERBdlr6V1CMDg", size: 2>, #<Treasure id: 3, user_id: 1, treasure_name: "Kapal", treasure_image: nil, description: "Kapal", hint: nil, location: "Unnamed Road", created_at: "2016-01-07 09:21:07", updated_at: "2016-01-07 09:21:07", treasure_id: "T3XQR", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942ba29c "POINT (101.76 3.5)">, city: "null", state: "Selangor", country: "Malaysia", difficulty: 2, google_place_id: "ChIJWU_xuCoTzDERsigXByaXof4", size: 3>, #<Treasure id: 1, user_id: 1, treasure_name: "Kelapa", treasure_image: nil, description: "Food", hint: nil, location: "Jalan Kiara 3", created_at: "2016-01-07 06:08:56", updated_at: "2016-01-07 06:08:56", treasure_id: "TJKQL", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9943647d8 "POINT (101.65 3.17)">, city: "Kuala Lumpur", state: "Wilayah Persekutuan Kuala Lumpur", country: "Malaysia", difficulty: 2, google_place_id: "ChIJ8fBgm-1IzDERPHAF2dYtWTc", size: 2>, #<Treasure id: 2, user_id: 1, treasure_name: "Pulau", treasure_image: nil, description: "Pulau", hint: nil, location: "Jalan Parit 4 Barat", created_at: "2016-01-07 09:20:47", updated_at: "2016-01-07 09:20:47", treasure_id: "TO1BR", location_point: #<RGeo::Geographic::SphericalPointImpl:0x3fe9942bd744 "POINT (101.0 3.7)">, city: "Sungai Besar", state: "Selangor", country: "Malaysia", difficulty: 2, google_place_id: "ChIJAfwEx2lgyzERU_zVy8TqaW0", size: 3>]> 

NOT: Ben alt sorgu söylendi does not düzen, muhtemelen bir dış çalışabilir katılmak. Böyle bir sorgu nasıl oluşturulur?

cevap

3

Aslında siparişinizin çalışmasını engelleyen birkaç şey var. Bahsettiğiniz gibi

  • Birincisi, bir alt sorguda herhangi ORDER fıkra - konum sorgusu içinde ne olduğunu - Nihai sonuç kümesinin sipariş için alakasız olacak. İkinci olarak, GROUP BY city numaralı ifadeniz, sonuçlarınızı kesin olarak belirtebilmenizi mantıksal olarak imkansız hale getirmektedir. Şehir X'de A hazinesine, mesafe = 10'a, Y şehirindeki hazine B'ye, şehirdeki X = mesafe = 15'e, mesafe = 15'de ise hazine C'ye sahip olduğunuzu varsayalım. City X, sonuçlarınızda birinci mi yoksa sonuncu mu gelecek? Bununla birlikte, bütün şehirlerin kabaca benzer bir alanda hazineler içerdiğini varsaymak makul olduğunu düşünüyorum, bu nedenle en yakın hazine tarafından sipariş vermek mantıklıdır. Bu sorunu halledebiliriz. Son olarak, Rails'in group().count numaralı rayı, sayımların değerlerinin bir hash değerini vermektedir. Bu API muhtemelen oldukça yenidir ve muhtemelen değişebilir (hashes gerçekten sipariş edilmemelidir, bence ve format çok genişletilemez). Bu yüzden güvenmek kötü bir fikir olabilir. Ancak, testlerimden itibaren , sonucunu istenen sırayla tükürüyor. Kısacası

, ne yapmamız gerek Sorgunuzun üst düzeyine için order taşımaktır.Sipariş fıkra toplama fonksiyonu kullanması gerekir Bunu yapmak için, (Ben en yakın hazine tarafından sipariş, MIN seçeceğiz) ve biz fantezi .from kodunu bırakabilirsiniz:

# I'm assuming this is on the Treasure model 
scope :nearestcitysubquery, ->() { 
    group('city') 
    .order("MIN(ST_Distance(treasures.location_point, 
     ST_GeographyFromText('SRID=4326;POINT(110.1862202 1.6031959)')))") 
    .count 
} 
+0

teşekkürler Robert Nübel, doğrulayacaktır tekniği. Bu arada, en yakın öğelerin sayısını sınırlamak için .limit() 'i nereye koyabilirim (örneğin sadece 30). Teşekkürler. – Axil

+0

'.count' yapılmadan önce (yani' group (...) .sipariş (...). Limit (30) .count'). Beklediğin gibi çalışmıyorsa haber ver. –

+0

Merhaba @Robert Nubel, sınır doğru değil. Şehir sayısını sınırlar (bu örnekte 30 şehirde). Sayım sayısını sınırlayabilir miyiz? – Axil

İlgili konular