Class: Parse::Constraint::ArraySizeConstraint

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

Overview

Note:

This constraint uses aggregation pipeline because Parse Server does not support the $size query operator natively.

Note:

This constraint uses MongoDB aggregation pipeline. While $expr expressions cannot utilize field indexes, aggregation is efficient for array size operations that would otherwise require client-side filtering.

Array size constraint using MongoDB aggregation. Parse Server does not natively support $size query constraint, so we use MongoDB aggregation pipeline with $expr and $size to check array length.

# Exact size match q.where :field.size => 2 q.where :tags.size => 5

# Comparison operators via hash q.where :tags.size => { gt: 3 } # size > 3 q.where :tags.size => { gte: 2 } # size >= 2 q.where :tags.size => { lt: 5 } # size < 5 q.where :tags.size => { lte: 4 } # size <= 4 q.where :tags.size => { ne: 0 } # size != 0

# Combine for range q.where :tags.size => { gte: 2, lt: 10 } # 2 <= size < 10

Constant Summary collapse

COMPARISON_OPERATORS =

Mapping of constraint keys to MongoDB comparison operators

{
  gt: "$gt",
  gte: "$gte",
  lt: "$lt",
  lte: "$lte",
  ne: "$ne",
  eq: "$eq",
}.freeze

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, register, #to_s

Constructor Details

This class inherits a constructor from Parse::Constraint

Instance Method Details

#buildHash

Returns the compiled constraint using aggregation pipeline.

Returns:

  • (Hash)

    the compiled constraint using aggregation pipeline.



578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
# File 'lib/parse/query/constraints.rb', line 578

def build
  value = formatted_value
  field_name = Parse::Query.format_field(@operation.operand)
  size_expr = { "$size" => { "$ifNull" => ["$#{field_name}", []] } }

  if value.is_a?(Integer)
    # Simple exact match
    raise ArgumentError, "#{self.class}: Size value must be non-negative" if value < 0

    pipeline = [
      {
        "$match" => {
          "$expr" => {
            "$eq" => [size_expr, value],
          },
        },
      },
    ]
  elsif value.is_a?(Hash)
    # Hash with comparison operators
    conditions = []

    value.each do |op, val|
      op_sym = op.to_sym
      unless COMPARISON_OPERATORS.key?(op_sym)
        raise ArgumentError, "#{self.class}: Unknown operator '#{op}'. Valid operators: #{COMPARISON_OPERATORS.keys.join(", ")}"
      end
      unless val.is_a?(Integer) && val >= 0
        raise ArgumentError, "#{self.class}: Value for '#{op}' must be a non-negative integer"
      end

      mongo_op = COMPARISON_OPERATORS[op_sym]
      conditions << { mongo_op => [size_expr, val] }
    end

    # Combine multiple conditions with $and
    expr = conditions.length == 1 ? conditions.first : { "$and" => conditions }

    pipeline = [
      {
        "$match" => {
          "$expr" => expr,
        },
      },
    ]
  else
    raise ArgumentError, "#{self.class}: Value must be an integer or hash with comparison operators (gt, gte, lt, lte, ne, eq)"
  end

  { "__aggregation_pipeline" => pipeline }
end

#sizeArraySizeConstraint

A registered method on a symbol to create the constraint.

Examples:

q.where :field.size => 2
q.where :field.size => { gt: 3, lte: 10 }

Returns:



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

register :size