Class: Parse::Constraint::NearSphereQueryConstraint
- Inherits:
-
Parse::Constraint
- Object
- Parse::Constraint
- Parse::Constraint::NearSphereQueryConstraint
- Defined in:
- lib/parse/query/constraints.rb
Overview
Add support $maxDistanceInKilometers (for kms) and $maxDistanceInRadians (for radian angle).
Equivalent to the ‘$nearSphere` Parse query operation. This is only applicable if the field is of type `GeoPoint`. This will query Parse and return a list of results ordered by distance with the nearest object being first.
q.where :field.near => geopoint
geopoint = Parse::GeoPoint.new(30.0, -20.0)
PlaceObject.all :location.near => geopoint
If you wish to constrain the geospatial query to a maximum number of miles, you can utilize the ‘max_miles` method on a `Parse::GeoPoint` object. This is equivalent to the `$maxDistanceInMiles` constraint used with `$nearSphere`.
q.where :field.near => geopoint.max_miles(distance)
# or provide a triplet includes max miles constraint
q.where :field.near => [lat, lng, miles]
geopoint = Parse::GeoPoint.new(30.0, -20.0)
PlaceObject.all :location.near => geopoint.max_miles(10)
Constant Summary collapse
- KM_PER_RADIAN =
Conversion factors mirror WithinSphereQueryConstraint so the cap below is unit-agnostic.
6371.0- MILES_PER_RADIAN =
3958.8- MAX_RADIANS =
Whole-sphere cap (π radians ≈ 6371π km ≈ 3958.8π miles). A ‘$nearSphere` with a larger `$maxDistanceIn*` defeats the `2dsphere` early-termination optimization and degenerates to a full geo scan.
Math::PI
Instance Attribute Summary
Attributes inherited from Parse::Constraint
#operand, #operation, #operator, #value
Instance Method Summary collapse
-
#build ⇒ Hash
The compiled constraint.
-
#near ⇒ NearSphereQueryConstraint
A registered method on a symbol to create the constraint.
Methods inherited from Parse::Constraint
#as_json, constraint_keyword, create, formatted_value, #formatted_value, #initialize, #key, #precedence, register, #to_s
Constructor Details
This class inherits a constructor from Parse::Constraint
Instance Method Details
#build ⇒ Hash
Returns the compiled constraint.
1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 |
# File 'lib/parse/query/constraints.rb', line 1768 def build point = formatted_value max_distance = nil unit = :miles if point.is_a?(Array) && point.count > 1 if point.count >= 3 max_distance = point[2] # max_kilometers / max_radians tag the array with their unit # symbol in the 4th slot so we can dispatch to the right # Parse operator key. max_miles leaves slot 3 nil and the # default :miles applies. unit = point[3] if [:km, :radians].include?(point[3]) end point = { __type: "GeoPoint", latitude: point[0], longitude: point[1] } end if max_distance.present? && max_distance > 0 # Cap radius at whole-sphere coverage (π radians) regardless # of the chosen unit. Without this cap, an attacker-controlled # `max_*` (e.g. user-supplied km) can submit a huge value and # force a full-collection scan. radians_for_check = case unit when :km then max_distance.to_f / KM_PER_RADIAN when :radians then max_distance.to_f else max_distance.to_f / MILES_PER_RADIAN end if radians_for_check > MAX_RADIANS raise ArgumentError, "[Parse::Query] `near` max distance #{max_distance} #{unit} " \ "(#{radians_for_check} radians) exceeds whole-sphere coverage " \ "(π radians). A radius that large defeats the 2dsphere index " \ "and degenerates $nearSphere into a full collection scan." end distance_key = case unit when :km then :$maxDistanceInKilometers when :radians then :$maxDistance else :$maxDistanceInMiles end return { @operation.operand => { key => point, distance_key => max_distance.to_f } } end { @operation.operand => { key => point } } end |
#near ⇒ NearSphereQueryConstraint
A registered method on a symbol to create the constraint. Maps to Parse operator “$nearSphere”.
1754 |
# File 'lib/parse/query/constraints.rb', line 1754 constraint_keyword :$nearSphere |