Class: Parse::Constraint::WithinSphereQueryConstraint

Inherits:
Parse::Constraint show all
Defined in:
lib/parse/query/constraints.rb

Overview

Equivalent to the $geoWithin Parse query operation with $centerSphere subconstraint. Filters a GeoPoint column by subscription in a circular region defined by a center point and a radius. Unlike :field.near => geopoint.max_*(N), this constraint does NOT order results by distance, which makes it cheap and composable inside $or branches and aggregation pipelines.

The radius is in radians at the wire level. For convenience the DSL accepts an Array tuple [geopoint, distance, unit] where unit may be :radians (default), :km / :kilometers, or :miles; the SDK converts to radians using mean-Earth-radius 6371 km / 3958.8 mi.

q.where :location.within_sphere => [center, 5, :km] q.where :location.within_sphere => [center, 10, :miles] q.where :location.within_sphere => [center, 0.001] # radians

Version:

  • 4.4.0 (requires Parse Server with $centerSphere support)

Constant Summary collapse

KM_PER_RADIAN =
6371.0
MILES_PER_RADIAN =
3958.8
MAX_RADIANS =

Whole-sphere radius. $centerSphere with a radius greater than π radians covers the entire sphere — a query that returns every document in the collection and trivially defeats any 2dsphere index. Cap here so attacker-controlled radii (e.g. URL params forwarded into the constraint) can't degenerate into a full-collection scan.

Math::PI

Instance Attribute Summary

Attributes inherited from Parse::Constraint

#operand, #operation, #operator, #value

Instance Method Summary collapse

Methods inherited from Parse::Constraint

#as_json, constraint_keyword, create, formatted_value, #formatted_value, #initialize, #key, #precedence, #regex_unicode_option, register, #to_s

Constructor Details

This class inherits a constructor from Parse::Constraint

Instance Method Details

#buildHash

Returns the compiled constraint.

Returns:

  • (Hash)

    the compiled constraint.



2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
# File 'lib/parse/query/constraints.rb', line 2008

def build
  value = formatted_value
  unless value.is_a?(Array) && value.length >= 2
    raise ArgumentError, "[Parse::Query] Invalid value for `within_sphere` constraint: " \
                         "expected [geopoint, distance, unit?]."
  end

  point, distance, unit = value[0], value[1], (value[2] || :radians)
  unless point.is_a?(Parse::GeoPoint)
    raise ArgumentError, "[Parse::Query] `within_sphere` first element must be a Parse::GeoPoint."
  end
  unless distance.is_a?(Numeric) && distance > 0
    raise ArgumentError, "[Parse::Query] `within_sphere` distance must be a positive number."
  end

  radians =
    case unit
    when :radians then distance.to_f
    when :km, :kilometers then distance.to_f / KM_PER_RADIAN
    when :miles then distance.to_f / MILES_PER_RADIAN
    else
      raise ArgumentError, "[Parse::Query] `within_sphere` unit must be :radians, :km, or :miles."
    end

  if radians > MAX_RADIANS
    raise ArgumentError, "[Parse::Query] `within_sphere` radius #{distance} #{unit} " \
                         "(#{radians} radians) exceeds whole-sphere coverage (π radians). " \
                         "A radius that large covers the entire sphere and degenerates " \
                         "$centerSphere into a full-collection scan."
  end

  # MongoDB's $centerSphere expects [longitude, latitude]
  # (GeoJSON convention), not Parse's [latitude, longitude] order.
  center = [point.longitude, point.latitude]
  # `$centerSphere` is a native MongoDB geo operator, not a
  # documented Parse Server REST find operator. Mark this
  # constraint mongo-direct-only so the query layer auto-routes
  # to {Parse::Query#results_direct}; callers without a mongo
  # connection or master-key/scoped auth will get
  # `MongoDirectRequired` rather than a silently-wrong REST
  # result.
  {
    @operation.operand => { :$geoWithin => { :$centerSphere => [center, radians] } },
    "__mongo_direct_only" => true,
  }
end

#within_sphereWithinSphereQueryConstraint

A registered method on a symbol to create the constraint. Maps to Parse operator "$geoWithin" with "$centerSphere" subconstraint.

Examples:

q.where :location.within_sphere => [center_geopoint, 5, :km]

Returns:



1994
# File 'lib/parse/query/constraints.rb', line 1994

constraint_keyword :$geoWithin