You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by to...@apache.org on 2015/09/10 02:34:07 UTC
[05/26] couchdb-mango git commit: Handle extra <<>> when elemMatch
normalizes selector
Handle extra <<>> when elemMatch normalizes selector
When $elemMatch is applied to non-objects such as:
{"results":{"$elemMatch": {"$gte": 80, "$lt": 85}}},
our normalizer modifies the selector to include <<>>. This
causes issues for our path_str and match functions. This
fix addresses those issues by removing the <<>> from the selector
and also not adding a period when a Part is <<>>.
BugzId: 44817
Project: http://git-wip-us.apache.org/repos/asf/couchdb-mango/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mango/commit/10fcac2b
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mango/tree/10fcac2b
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mango/diff/10fcac2b
Branch: refs/heads/master
Commit: 10fcac2be08f22395935bd938d5dccf5e8d71ac9
Parents: ca5ff7b
Author: Tony Sun <to...@cloudant.com>
Authored: Tue Aug 25 11:26:50 2015 -0700
Committer: Tony Sun <to...@cloudant.com>
Committed: Tue Aug 25 13:23:53 2015 -0700
----------------------------------------------------------------------
src/mango_selector.erl | 15 +++++++++++++++
src/mango_selector_text.erl | 8 +++++++-
test/06-basic-text-test.py | 18 ++++++++++++++++++
test/friend_docs.py | 4 +++-
4 files changed, 43 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/src/mango_selector.erl
----------------------------------------------------------------------
diff --git a/src/mango_selector.erl b/src/mango_selector.erl
index c008a4c..21c55ae 100644
--- a/src/mango_selector.erl
+++ b/src/mango_selector.erl
@@ -411,6 +411,21 @@ match({[{<<"$all">>, Args}]}, Values, _Cmp) when is_list(Values) ->
match({[{<<"$all">>, _Args}]}, _Values, _Cmp) ->
false;
+%% This is for $elemMatch and possibly $in because of our normalizer.
+%% A selector such as {"field_name": {"$elemMatch": {"$gte": 80, "$lt": 85}}}
+%% gets normalized to:
+%% {[{<<"field_name">>,
+%% {[{<<"$elemMatch">>,
+%% {[{<<"$and">>, [
+%% {[{<<>>,{[{<<"$gte">>,80}]}}]},
+%% {[{<<>>,{[{<<"$lt">>,85}]}}]}
+%% ]}]}
+%% }]}
+%% }]}.
+%% So we filter out the <<>>.
+match({[{<<>>, Arg}]}, Values, Cmp) ->
+ match(Arg, Values, Cmp);
+
% Matches when any element in values matches the
% sub-selector Arg.
match({[{<<"$elemMatch">>, Arg}]}, Values, Cmp) when is_list(Values) ->
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/src/mango_selector_text.erl
----------------------------------------------------------------------
diff --git a/src/mango_selector_text.erl b/src/mango_selector_text.erl
index 74a4012..24d4ad1 100644
--- a/src/mango_selector_text.erl
+++ b/src/mango_selector_text.erl
@@ -274,7 +274,13 @@ path_str([Part], Acc) ->
% during recursion of convert.
[Part | Acc];
path_str([Part | Rest], Acc) ->
- path_str(Rest, [<<".">>, Part | Acc]).
+ case Part of
+ % do not append a period if Part is blank
+ <<>> ->
+ path_str(Rest, [Acc]);
+ _ ->
+ path_str(Rest, [<<".">>, Part | Acc])
+ end.
type_str(Value) when is_number(Value) ->
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/test/06-basic-text-test.py
----------------------------------------------------------------------
diff --git a/test/06-basic-text-test.py b/test/06-basic-text-test.py
index baf912b..670fad5 100644
--- a/test/06-basic-text-test.py
+++ b/test/06-basic-text-test.py
@@ -404,6 +404,24 @@ class ElemMatchTests(mango.FriendDocsTextTests):
def setUpClass(klass):
raise unittest.SkipTest('text index is not supported yet')
+ def test_elem_match_non_object(self):
+ q = {"bestfriends":{
+ "$elemMatch":
+ {"$eq":"Wolverine", "$eq":"Cyclops"}
+ }
+ }
+ docs = self.db.find(q)
+ print len(docs)
+ assert len(docs) == 1
+ assert docs[0]["bestfriends"] == ["Wolverine", "Cyclops"]
+
+ q = {"results": {"$elemMatch": {"$gte": 80, "$lt": 85}}}
+
+ docs = self.db.find(q)
+ print len(docs)
+ assert len(docs) == 1
+ assert docs[0]["results"] == [82, 85, 88]
+
def test_elem_match(self):
q = {"friends": {
"$elemMatch":
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/test/friend_docs.py
----------------------------------------------------------------------
diff --git a/test/friend_docs.py b/test/friend_docs.py
index 8bba58d..ec2c082 100644
--- a/test/friend_docs.py
+++ b/test/friend_docs.py
@@ -461,7 +461,8 @@ DOCS = [
},
"type": "personal"
}
- ]
+ ],
+ "bestfriends" : ["Wolverine", "Cyclops"]
},
{
"_id": "54a431719faa420a5b4fbeb0",
@@ -530,6 +531,7 @@ DOCS = [
"type": "work"
}
]
+ "results": [ 82, 85, 88 ]
},
{
"_id": "54a4317132f2c81561833259",