Mongoid query by value or default value

2019-07-07 13:56发布

I've just updated one of my models with a boolean field. I've set a default value for the field to true. How can I query for this field in such a way that I get all documents with this field set to true or doesn't have this field (default value).

1条回答
女痞
2楼-- · 2019-07-07 14:43

To find documents that don't have a particular key, you want to use $exists:

$exists
Syntax: { field: { $exists: <boolean> } }

$exists selects the documents that contain the field if <boolean> is true. If <boolean> is false, the query only returns the documents that do not contain the field. $exists does match documents that contain the field that stores the null value.

So the existence check would look like:

Model.where(:field.exists => false)
Model.where(:field => { :$exists => false })

Note that the first :field.exists form becomes the second form before it gets sent to MongoDB; I mention this because you won't be able to use :field elsewhere in the query without using $and or $or to combine the clauses: the :field.exists expansion can lead to keys in the query Hash overwriting each other. You won't have this problem here but a reminder can't hurt.

Looking for true is easy:

Model.where(:field => true)

You want either one so combine them with $or:

Model.where(:$or => [
  { :field.exists => false },
  { :field        => true  }
])

If :field might be there but have a null value then you could use { :field => nil } to match documents where :field is null or not there at all:

Model.where(:$or => [
  { :field => null  },
  { :field => true  }
])
# or
Model.where(:field.in => [ null, true ]) # This is probably the one you want

There's also { :field => { :$type => 10 } } if you're looking for things that are there and explicitly null. Now might be a good time for a quick review of the MongoDB FAQ:

How do I query for fields that contain null values?

查看更多
登录 后发表回答