2017-04-11 14 views
6

Tôi đang sử dụng Firebase để lưu trữ Người dùng với vĩ độ và kinh độ được quét gần đây nhất của họ.Truy vấn cho các vị trí lân cận

Một mục trông như thế này:

"Bdhwu37Jdmd28DmenHahd221" : { 
    "country_code" : "at", 
    "firstname" : "John", 
    "gender" : "m", 
    "lat" : 11.2549387, 
    "lon" : 17.3419559 
} 

Bất cứ khi nào một người dùng nhấn một nút cụ thể "tìm kiếm", tôi muốn chức năng căn cứ hỏa lực của tôi để lấy những người gần nhất với người gửi yêu cầu.

Vì Firebase chỉ cho phép quering sau một trường, tôi quyết định thêm mã quốc gia, để loại có một số hạn chế về phạm vi và truy vấn cho trường đó. Nhưng nó vẫn còn siêu chậm khi tôi tải mọi người dùng của một quốc gia cụ thể và sau đó kiểm tra khoảng cách nhỏ nhất giữa một người dùng cụ thể và tất cả những người dùng khác trong cùng một quốc gia.

Đã có 5 người dùng, chức năng sẽ mất 40 giây để đạt được kết quả.

Tôi cũng đã đọc về các chỉ mục phức hợp, nhưng tôi sẽ cần bằng cách nào đó kết hợp vĩ độ và kinh độ và truy vấn cho cả hai trường.

Có cách nào để nhận truy vấn thứ hai và thứ ba ở đây không (ví dụ: tìm kiếm cùng một country_code và sau đó cho một vĩ độ và vĩ độ tương tự) hoặc tôi phải giải quyết điều này bên trong mã máy chủ của mình?

+4

https://github.com/firebase/geofire – cartant

Trả lời

12

Cơ sở dữ liệu Firebase chỉ có thể truy vấn bởi một thuộc tính duy nhất. Vì vậy, cách để lọc các giá trị vĩ độ và kinh độ là kết hợp chúng thành một thuộc tính duy nhất. Thuộc tính kết hợp đó phải giữ lại các đặc điểm lọc mà bạn muốn cho các giá trị số, chẳng hạn như khả năng lọc cho một dải ô.

Trong khi điều này lúc đầu có vẻ không thể, thực tế nó đã được thực hiện dưới dạng Geohashes. Một vài trong số những đặc điểm của nó:

  1. Nó là một cấu trúc dữ liệu không gian thứ bậc mà subdivides gian vào xô hình dạng lưới

Vì vậy: Geohashes chia không gian thành một mạng lưới các xô, mỗi nhóm được xác định bằng một chuỗi.

  1. Geohashes cung cấp các đặc tính như độ chính xác tùy ý và khả năng dần dần xoá các ký tự từ cuối của mã để giảm kích thước của nó (và dần dần mất đi độ chính xác).

càng dài chuỗi, càng lớn thì khu vực đó xô bao gồm

  1. Như một hệ quả của sự suy thoái chính xác dần dần, những nơi lân cận sẽ thường xuyên (nhưng không phải lúc nào) giới thiệu các tiền tố tương tự. Tiền tố được chia sẻ càng dài thì càng gần hai địa điểm.

Chuỗi bắt đầu bằng cùng một ký tự gần nhau.

Kết hợp những đặc điểm này và bạn có thể thấy lý do tại sao những Geohashes này hấp dẫn để sử dụng với Cơ sở dữ liệu Firebase: chúng kết hợp vĩ độ và kinh độ của một vị trí thành một chuỗi. gần giống nhau. Ma thuật!

Firebase cung cấp thư viện có tên Geofire, sử dụng Geohashes để triển khai hệ thống định vị địa lý trên cơ sở dữ liệu thời gian thực của nó. Thư viện có sẵn cho JavaScript, JavaObjective-C/Swift.

Để tìm hiểu thêm về Geofire, hãy kiểm tra:

+0

Cảm ơn bạn, tôi sẽ đọc và dùng thử. Có thể, chức năng đám mây siêu chậm? Chỉ truy vấn cho 3 người đưa tôi như 40 giây mỗi lần (không chỉ lần đầu tiên) và tôi chỉ truy cập 2 cơ sở dữ liệu. – Thomas

+0

Nếu bạn luôn có hiệu suất mà bạn nghĩ là không hợp lý (ngay cả khi bạn xem xét rằng Chức năng đám mây đang ở giai đoạn thử nghiệm), hãy mở câu hỏi với [mã tối thiểu tái tạo vấn đề đó] (http://stackoverflow.com/help/mcve) . –

+0

GeoFire hoạt động tốt, nhưng tôi không thể làm cho nó hoạt động, khi vị trí của người dùng được lồng trong userdata. Các điểm tham chiếu geoFire của tôi tại "/ user" và dữ liệu geoFire của tôi là/user/$ uid/location, geoFire có tự động tìm kiếm các trường lồng nhau hay tôi phải định nghĩa một nơi nào đó, tại đó giá trị "g" được tìm thấy? Dường như thuật toán tìm kiếm "g" ngay bên dưới mục nhập "/ người dùng" của tôi và không phải ở "vị trí" – Thomas

Các vấn đề liên quan