@@ -74,7 +74,12 @@ class Mongo
74
74
# @return [ Integer ] The number of matches.
75
75
def count ( options = { } , &block )
76
76
return super ( &block ) if block_given?
77
- view . count_documents ( options )
77
+
78
+ if valid_for_count_documents?
79
+ view . count_documents ( options )
80
+ else
81
+ view . count ( options )
82
+ end
78
83
end
79
84
80
85
# Get the estimated number of documents matching the query.
@@ -1038,6 +1043,24 @@ def process_raw_docs(raw_docs, limit)
1038
1043
limit ? docs : docs . first
1039
1044
end
1040
1045
1046
+ # Queries whether the current context is valid for use with
1047
+ # the #count_documents? predicate. A context is valid if it
1048
+ # does not include a `$where` operator.
1049
+ #
1050
+ # @return [ true | false ] whether or not the current context
1051
+ # excludes a `$where` operator.
1052
+ def valid_for_count_documents? ( hash = view . filter )
1053
+ # Note that `view.filter` is a BSON::Document, and all keys in a
1054
+ # BSON::Document are strings; we don't need to worry about symbol
1055
+ # representations of `$where`.
1056
+ hash . keys . each do |key |
1057
+ return false if key == '$where'
1058
+ return false if hash [ key ] . is_a? ( Hash ) && !valid_for_count_documents? ( hash [ key ] )
1059
+ end
1060
+
1061
+ true
1062
+ end
1063
+
1041
1064
def raise_document_not_found_error
1042
1065
raise Errors ::DocumentNotFound . new ( klass , nil , nil )
1043
1066
end
0 commit comments