Skip to content

Commit

Permalink
Improve update op $pull
Browse files Browse the repository at this point in the history
  • Loading branch information
davidlatwe committed Jul 4, 2018
1 parent bcb71e7 commit 8ac76c4
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 12 deletions.
26 changes: 14 additions & 12 deletions montydb/engine/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from ..errors import WriteError
from .core import FieldWriteError, Weighted, SimpleGetter, _cmp_decimal
from .queries import QueryFilter
from .helpers import is_numeric_type, is_duckument_type, PY36
from .helpers import is_numeric_type, is_duckument_type


class Updator(object):
Expand Down Expand Up @@ -433,16 +433,17 @@ def pop(old_val, pop_ind, field_info):
return _pop


def _lose_top_order(value):
if PY36 and is_duckument_type(value):
# To lose top level key order, sort alphabetically to unify them.
return {k: v for k, v in sorted(value.items())}
def parse_pull(field, value_or_conditions, array_filters):
if is_duckument_type(value_or_conditions):
query_spec = {}
for k, v in value_or_conditions.items():
if not k[:1] == "$":
query_spec[".".join((field, k))] = v
else:
query_spec[field] = {k: v}
queryfilter = QueryFilter(query_spec)
else:
return value


def parse_pull(field, value, array_filters):
queryfilter = QueryFilter({"": _lose_top_order(value)})
queryfilter = QueryFilter({field: value_or_conditions})

def _pull(fieldwalker):
def pull(old_val, _, field_info):
Expand All @@ -457,13 +458,14 @@ def pull(old_val, _, field_info):

new_array = []
for elem in old_val:
result = queryfilter({"": _lose_top_order(elem)})
result = queryfilter({field: elem})

if not result:
new_array.append(elem)
return new_array

try:
fieldwalker.go(field).set(value, pull, array_filters)
fieldwalker.go(field).set(None, pull, array_filters)
except FieldWriteError as err:
msg = err.message if hasattr(err, 'message') else str(err)
raise WriteError(msg, code=err.code)
Expand Down
95 changes: 95 additions & 0 deletions tests/test_engine/test_update/test_update_pull.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,98 @@ def test_update_pull_6(monty_update, mongo_update):
assert next(monty_c) == {"a": [{"x": {"b": 1, "c": 1}}]}
else:
assert next(monty_c) == {"a": []}


def test_update_pull_7(monty_update, mongo_update):
docs = [
{"a": [{"x": {"b": 1, "c": 1}, "y": 1},
{"x": {"c": 1, "b": 1}, "y": 1}]},
{"a": [{"y": 1, "x": {"b": 1, "c": 1}},
{"y": 1, "x": {"c": 1, "b": 1}}]}
]
spec = {"$pull": {"a": {"x": {"b": 1, "c": 1}, "y": 1}}}

monty_c = monty_update(docs, spec)
mongo_c = mongo_update(docs, spec)

assert next(mongo_c) == next(monty_c)
monty_c.rewind()
if PY36:
assert monty_c[0] == {"a": [{"x": {"c": 1, "b": 1}, "y": 1}]}
assert monty_c[1] == {"a": [{"y": 1, "x": {"c": 1, "b": 1}}]}
else:
assert monty_c[0] == {"a": []}
assert monty_c[1] == {"a": []}


def test_update_pull_8(monty_update, mongo_update):
docs = [
{"a": [1, 2, 3, 4]}
]
spec = {"$pull": {"a": {"$gt": 2}}}

monty_c = monty_update(docs, spec)
mongo_c = mongo_update(docs, spec)

assert next(mongo_c) == next(monty_c)
monty_c.rewind()
assert next(monty_c) == {"a": [1, 2]}


def test_update_pull_9(monty_update, mongo_update):
docs = [
{"a": ["q", "w", "e", "r"], "b": ["z", "x", "c", "v"]}
]
spec = {"$pull": {"a": {"$in": ["e", "w"]}, "b": "x"}}

monty_c = monty_update(docs, spec)
mongo_c = mongo_update(docs, spec)

assert next(mongo_c) == next(monty_c)
monty_c.rewind()
assert next(monty_c) == {"a": ["q", "r"], "b": ["z", "c", "v"]}


def test_update_pull_10(monty_update, mongo_update):
docs = [
{"a": [{"i": "A", "s": 5}, {"i": "B", "s": 8, "c": "blah"}]}
]
spec = {"$pull": {"a": {"s": 8, "i": "B"}}}

monty_c = monty_update(docs, spec)
mongo_c = mongo_update(docs, spec)

assert next(mongo_c) == next(monty_c)
monty_c.rewind()
assert next(monty_c) == {"a": [{"i": "A", "s": 5}]}


def test_update_pull_11(monty_update, mongo_update):
docs = [
{"a": [{"i": "A", "s": 5}, {"i": "B", "s": 8, "c": "blah"}]}
]
spec = {"$pull": {"a": {"$elemMatch": {"s": 8, "i": "B"}}}}

monty_c = monty_update(docs, spec)
mongo_c = mongo_update(docs, spec)

assert next(mongo_c) == next(monty_c)
monty_c.rewind()
assert next(monty_c) == {"a": [{"i": "A", "s": 5},
{"i": "B", "s": 8, "c": "blah"}]}


def test_update_pull_12(monty_update, mongo_update):
docs = [
{"a": [{"w": [{"q": 1, "a": 4}, {"q": 2, "a": 6}]},
{"w": [{"q": 1, "a": 8}, {"q": 2, "a": 9}]}]}
]
spec = {"$pull": {"a": {"w": {"$elemMatch": {"q": 2, "a": {"$gte": 8}}}}}}

monty_c = monty_update(docs, spec)
mongo_c = mongo_update(docs, spec)

assert next(mongo_c) == next(monty_c)
monty_c.rewind()
assert next(monty_c) == {"a": [{"w": [{"q": 1, "a": 4},
{"q": 2, "a": 6}]}]}

0 comments on commit 8ac76c4

Please sign in to comment.