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.



549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
# File 'lib/parse/query/constraints.rb', line 549

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:



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

register :size