forked from mongodb/mongoid
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request mongodb#4300 from jonhyman/feature/elemMatch-matches
Add support for $elemMatch in Matchable#matches?
- Loading branch information
Showing
4 changed files
with
241 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# encoding: utf-8 | ||
module Mongoid | ||
module Matchable | ||
|
||
class ElemMatch < Default | ||
|
||
# Return true if a given predicate matches a sub document entirely | ||
# | ||
# @example Do the values match? | ||
# matcher.matches?({"$elemMatch" => {"a" => 1, "b" => 2}}) | ||
# | ||
# @param [ Hash ] value The values to check. | ||
# | ||
# @return [ true, false ] If the values match. | ||
def matches?(value) | ||
if !@attribute.is_a?(Array) || !value.kind_of?(Hash) || !value["$elemMatch"].kind_of?(Hash) | ||
return false | ||
end | ||
|
||
return @attribute.any? do |sub_document| | ||
value["$elemMatch"].all? do |k, v| | ||
Matchable.matcher(sub_document, k, v).matches?(v) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
require "spec_helper" | ||
|
||
describe Mongoid::Matchable::ElemMatch do | ||
|
||
let(:attribute) {[{"a" => 1, "b" => 2}, {"a" => 2, "b" => 2}, {"a" => 3, "b" => 1}]} | ||
let(:matcher) do | ||
described_class.new(attribute) | ||
end | ||
|
||
describe "#matches?" do | ||
|
||
context "when the attribute is not an array" do | ||
|
||
let(:attribute) {"string"} | ||
|
||
it "returns false" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => 1})).to be false | ||
end | ||
end | ||
|
||
context "when the $elemMatch is not a hash" do | ||
|
||
let(:attribute) {"string"} | ||
|
||
it "returns false" do | ||
expect(matcher.matches?("$elemMatch" => [])).to be false | ||
end | ||
end | ||
|
||
context "when there is a sub document that matches the criteria" do | ||
|
||
it "returns true" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => 1})).to be true | ||
end | ||
|
||
context "when evaluating multiple fields of the subdocument" do | ||
|
||
it "returns true" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => 1, "b" => 2})).to be true | ||
end | ||
|
||
context "when the $elemMatch document keys are out of order" do | ||
|
||
it "returns true" do | ||
expect(matcher.matches?("$elemMatch" => {"b" => 2, "a" => 1})).to be true | ||
end | ||
end | ||
end | ||
|
||
context "when using other operators that match" do | ||
|
||
it "returns true" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => {"$in" => [1]}, "b" => {"$gt" => 1}})).to be true | ||
end | ||
end | ||
end | ||
|
||
context "when there is not a sub document that matches the criteria" do | ||
|
||
it "returns false" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => 10})).to be false | ||
end | ||
|
||
context "when evaluating multiple fields of the subdocument" do | ||
|
||
it "returns false" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => 1, "b" => 3})).to be false | ||
end | ||
end | ||
|
||
context "when using other operators that do not match" do | ||
|
||
it "returns true" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => {"$in" => [1]}, "b" => {"$gt" => 10}})).to be false | ||
end | ||
end | ||
end | ||
|
||
context "when using a criteria that matches partially but not a single sub document" do | ||
|
||
it "returns false" do | ||
expect(matcher.matches?("$elemMatch" => {"a" => 3, "b" => 2})).to be false | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters