Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-4911

Range expansion must use $elemMatch to ensure both $gte and $lte match the same array element

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 8.0.1
    • Affects Version/s: None
    • Component/s: Query
    • Labels:
      None
    • Major Change

      Suppose we have a job with two tasks:

        job = Job.new(tasks: [
          Task.new(name: 'Clean house', hours: 12),
          Task.new(name: 'Clean office', hours: 16),
        ])
      

      If we try to find a task with the number of hours in a specified range, we might say:

        job.tasks.where(:hours.gte => 13, :hours.lte => 14).first
      

      Mongoid 7.1 and the tree in 4781 so far both return nil in this case, but the server (queried on the job, not on tasks since only top-level documents can be queried by the server) would apply the two conditions independently from the top level and return the job.

      This becomes more of an issue when the argument is a single value, as would be the case with Range:

        job.tasks.where(hours: 13..14).first
      

      This query does not return any results in Mongoid 7.1 or with the 4781 tree; however, when the equivalent server query is used, it returns the job where none of the tasks individually satisfy the hours requirement:

      irb(main):023:0> Job.where('tasks.hours' => 13..14).first
      => #<Job _id: 5efa75932c97a636958475ac, >
      irb(main):025:0> Job.where('tasks.hours' => 13..14).first.tasks.map(&:hours)
      => [12, 16]
      

            Assignee:
            neil.shweky@mongodb.com Neil Shweky (Inactive)
            Reporter:
            oleg.pudeyev@mongodb.com Oleg Pudeyev (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: