adds operators $sizeLte and $sizeGte
Overview
- supports inequality matches for
$size- example: between 10 and 20 customers in array
-
"doc.customers": {"$sizeGte": 10} -
"doc.customers": {"$sizeLte": 20}
-
- example: between 10 and 20 customers in array
Testing recommendations
Tests are added to
- src/mango/test/03-operator-test.py
Related Issues or Pull Requests
None
Checklist
- [ ] Code is written and works correctly
- [ ] Changes are covered by tests
- [ ] Any new configurable parameters are documented in
rel/overlay/etc/default.ini - [ ] A PR for documentation changes has been made in https://github.com/apache/couchdb-documentation
Thanks for the contribution @hklarner. On a broader question the new operators you are creating:
-
$sizeGte -
$sizeLte
have no precedence in MongoDB which was the original inspiration for the MongoDB language. If I'm reading the MongoDB docs right, the MongoDB way of performing this query would be to allow the following syntax:
{
"selector": {
"customers": {
"$size:": { "$gte": 20}
}
}
}
The advantage of this approach is that
a) we already have a $size operator.
b) we have plenty of other comparison operators $eq, $gte etc etc
c) it wouldn't be creating new operators that differ from the "MongoDB way"
Note that currently the Mango query parser doesn't support this syntax, but I'm suggesting it could be modified to, rather than adding lots of new $size... operators.
What do you thinkg @hklarner & @garrensmith?
@glynnbird I see. Agreed, the MongoDB consistency is preferable. But I don't know how to implement it :sweat_smile:
@hklarner take a look at some of the other operators that handle nested values. Maybe $and and look at implementing something similar.
Hi @hklarner,
I was checking this. It seems quite simple to introduce nesting the behaviour for the $size operator. I've been testing with these changes and seems to work.
--- a/src/mango/src/mango_selector.erl
+++ b/src/mango/src/mango_selector.erl
@@ -145,6 +145,8 @@ norm_ops({[{<<"$keyMapMatch">>, Arg}]}) ->
norm_ops({[{<<"$size">>, Arg}]}) when is_integer(Arg), Arg >= 0 ->
{[{<<"$size">>, Arg}]};
+norm_ops({[{<<"$size">>, {_}=Arg}]}) ->
+ {[{<<"$size">>, norm_ops(Arg)}]};
norm_ops({[{<<"$size">>, Arg}]}) ->
?MANGO_ERROR({bad_arg, '$size', Arg});
@@ -581,8 +583,10 @@ match({[{<<"$regex">>, Regex}]}, Value, _Cmp) when is_binary(Value) ->
match({[{<<"$regex">>, _}]}, _Value, _Cmp) ->
false;
-match({[{<<"$size">>, Arg}]}, Values, _Cmp) when is_list(Values) ->
+match({[{<<"$size">>, Arg}]}, Values, _Cmp) when is_list(Values), is_integer(Arg) ->
length(Values) == Arg;
+match({[{<<"$size">>, Arg}]}, Values, _Cmp) when is_list(Values) ->
+ match(Arg, length(Values), _Cmp);
match({[{<<"$size">>, _}]}, _Value, _Cmp) ->
false;
I hope this could help.
@jjrodrig that's great! Hey, because of your answer on stackoverflow I opened this PR! Thanks for helping.
@hklarner : https://github.com/apache/couchdb/pull/3568 is very close to a merge. Do you want me to hold off with it so that this can be merged before?
@bessbd no, because I won't be able to continue with this for at least another week. All I have to do to be up to date is pull before I continue, right?
@bessbd no, because I won't be able to continue with this for at least another week. All I have to do to be up to date is pull before I continue, right?
That's pretty much it. In case you are changing files that are modified by the reformat, the conflict resolution may become a little difficult, but that shouldn't be a big deal. In case you need help with anything, please let me know.