Podłączenie wewnętrzne ACTiVERECORD


Próbuję przekonwertować „surowe” zapytanie PostGIS SQL na kwerendę Rails ActiveRecord. Moim celem jest konwersja dwóch kolejnych żądań ActiveRecord (każde trwa ~ 1 ms)) w jedno żądanie ActiveRecord (~ 1 ms). Używając poniższego SQL z
ActiveRecord :: Base.connection.execute
byłem w stanie potwierdzić redukcję czasu.
Więc moją bezpośrednią prośbą jest pomoc w konwersji tego żądania na żądanie ActiveRecord (i najlepszy sposób, aby to zrobić).
SELECT COUNT(*)
FROM "users"
INNER JOIN ( SELECT "centroid"
FROM "zip_caches"
WHERE "zip_caches"."postalcode" = '<postalcode>') AS "sub" ON ST_Intersects("users"."vendor_coverage", "sub"."centroid")
WHERE "users"."active" = 1;


NOTE

że wartość
& < postalcode & >
jest jedyną zmienną danych w tym żądaniu. Istnieją oczywiście dwa modele,
User
i
ZipCache
.
User
nie jest bezpośrednio powiązany z
ZipCache
.
Bieżące dwuetapowe żądanie ActiveRecord wygląda następująco.
zip = ZipCache.select(:centroid).where(postalcode: '<postalcode>').limit(1).first
User.where{st_intersects(vendor_coverage, zip.centroid)}.count

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Disclamer: Nigdy nie korzystałem z PostGIS

Po pierwsze, w ostatnim zapytaniu wygląda na to, że przegapiłeś część
WHERE "users". "Active" = 1;
.
Oto, co bym zrobił:
Najpierw dodaj obszar
active
dla użytkownika (do ponownego wykorzystania)
scope :active, -> { User.where(active: 1) }

Następnie, dla rzeczywistego zapytania, możesz mieć podzapytanie bez wykonywania go i używać go w połączeniach w modelu niestandardowym, na przykład:
subquery = ZipCache.select(:centroid).where(postalcode: '<postalcode>')
User.active
.joins("INNER JOIN (#{subquery.to_sql}) sub ON ST_Intersects(users.vendor_coverage, sub.centroid)")
.count

Pozwala to na zminimalizowanie surowego kodu SQL przy zachowaniu tylko jednego zapytania.
W każdym razie sprawdź rzeczywiste zapytanie sql w konsoli/dzienniku, ustawiając poziom rejestratora na debugowanie.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Niesamowite narzędzie

scuttle.io
http://www.scuttle.io/
idealny do konwersji zapytań takich jak to:
User.select(Arel.star.count).where(User.arel_table[:active].eq(1)).joins( User.arel_table.join(ZipCach.arel_table).on( Arel::Nodes::NamedFunction.new( 'ST_Intersects', [
User.arel_table[:vendor_coverage], Sub.arel_table[:centroid]
]
)
).join_sources)

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się