mongoid / origin

A Ruby DSL for building MongoDB queries
http://mongoid.org/en/origin/index.html
MIT License
62 stars 29 forks source link

$not criterion negation for regular expressions #45

Closed potatosalad closed 11 years ago

potatosalad commented 11 years ago

Here's a little excerpt MongoDB's documentation:

// The $not meta operator can be used to negate the check performed by a standard operator. For example:

db.customers.find( { name : { $not : /acme.*corp/i } } );

db.things.find( { a : { $not : { $mod : [ 10 , 1 ] } } } );

The operators reference in the manual has some more information on using $not with regular expressions.

This pull request is my attempt to add a :field.not criterion while maintaining the current query.not functionality. For regular expression values only, it allows the issue #44 syntax to work.

class User
  include Mongoid::Document
  field :name
end

# previously, this would not negate the regexp

User.not.where(name: /Andrew/).selector
  => { "name" => /Andrew/ }

# I changed the String and Symbol extensions to detect a regexp and consider it negatable

User.not.where(name: /Andrew/).selector
  => { "name" => { "$not" => /Andrew/ } }

# the following syntax also works

User.where(:name.not => /Andrew/).selector
  => { "name" => { "$not" => /Andrew/ } }

User.not(name: /Andrew/).selector
  => { "name" => { "$not" => /Andrew/ } }

# and finally, I have it check so double negatives don't happen

User.not.where(:name.not => /Andrew/).selector
  => { "name" => { "$not" => /Andrew/ } }

There may be a better way to accomplish including the $not for regular expressions, but I hope that the code and specs are helpful. Thanks!

durran commented 11 years ago

Thanks for the pull and the specs... I'll have a close look this weekend, but at first glance all looks great.