Skip to content

Commit

Permalink
MongoDB: read can be return most recent match with last_only
Browse files Browse the repository at this point in the history
  • Loading branch information
tsirif committed Nov 29, 2017
1 parent 94f8e09 commit cda014b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/metaopt/io/database/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def write(self, collection_name, data,
pass

@abstractmethod
def read(self, collection_name, query, selection=None):
def read(self, collection_name, query, selection=None, last_only=False):
"""Read a collection and return a value according to the query.
Parameters
Expand All @@ -117,6 +117,8 @@ def read(self, collection_name, query, selection=None):
Filter entries in collection.
selection : dict, optional
Elements of matched entries to return, the projection.
last_only : bool, optional
If True, return only the most recent entry that matches `query`.
:return: matched document[s]
Expand Down
10 changes: 7 additions & 3 deletions src/metaopt/io/database/mongodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,20 @@ def write(self, collection_name, data,
upsert=True)
return result.acknowledged

def read(self, collection_name, query, selection=None):
def read(self, collection_name, query, selection=None, last_only=False):
"""Read a collection and return a value according to the query.
.. seealso:: :meth:`AbstractDB.read` for argument documentation.
"""
dbcollection = self._db[collection_name]

cursor = dbcollection.find(query, selection)
dbdocs = list(cursor)
if not last_only:
cursor = dbcollection.find(query, selection)
dbdocs = list(cursor)
else:
# Return the most recent of the query
dbdocs = list(dbcollection.find(query, selection, sort=[('$natural', -1)], limit=1))

if not dbdocs:
return None
Expand Down
39 changes: 37 additions & 2 deletions tests/core/unittests/mongodb_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,24 +106,59 @@ def test_read_experiment(self, exp_config, moptdb):
'experiments', {'exp_name': 'supernaedo2', 'metadata.user': 'tsirif'})
assert loaded_config == exp_config[0][:2]

loaded_config = moptdb.read(
'experiments', {'exp_name': 'supernaedo2', 'metadata.user': 'tsirif'},
last_only=True)
assert loaded_config == exp_config[0][1]

loaded_config = moptdb.read('experiments',
{'exp_name': 'supernaedo2',
'metadata.user': 'tsirif',
'metadata.datetime': datetime(2017, 11, 22, 23, 0, 0)})
assert loaded_config == exp_config[0][0]

def test_read_default(self, exp_config, moptdb):
"""Fetch value(s) from an entry."""
"""Fetch value(s) from an entry.
- ``last_only`` is implicitly False
"""
value = moptdb.read(
'experiments', {'exp_name': 'supernaedo2', 'metadata.user': 'tsirif'},
selection={'algorithms': 1, '_id': 0})
assert value == [{'algorithms': exp_config[0][i]['algorithms']} for i in (0, 1)]

def test_read_last_only_false(self, exp_config, moptdb):
"""Fetch value(s) from an entry.
- ``last_only`` is explicitly False
"""
value = moptdb.read(
'experiments', {'exp_name': 'supernaedo2', 'metadata.user': 'tsirif'},
selection={'algorithms': 1, 'status': 1}, last_only=False)
assert value == [{'algorithms': exp_config[0][i]['algorithms'],
'status': exp_config[0][i]['status'],
'_id': exp_config[0][i]['_id']} for i in (0, 1)]

def test_read_last_only_true(self, exp_config, moptdb):
"""Fetch value(s) from an entry.
- ``last_only`` is explicitly False
"""
value = moptdb.read(
'experiments', {'exp_name': 'supernaedo2', 'metadata.user': 'tsirif'},
selection={'algorithms': 1, '_id': 0}, last_only=True)
assert value == {'algorithms': exp_config[0][1]['algorithms']}

def test_read_nothing(self, moptdb):
"""Fetch value(s) from an entry."""
value = moptdb.read(
'experiments', {'exp_name': 'not_found', 'metadata.user': 'tsirif'},
selection={'algorithms': 1})
selection={'algorithms': 1}, last_only=False)
assert value is None

value = moptdb.read(
'experiments', {'exp_name': 'not_found', 'metadata.user': 'tsirif'},
selection={'algorithms': 1}, last_only=True)
assert value is None

def test_read_trials(self, exp_config, moptdb):
Expand Down

0 comments on commit cda014b

Please sign in to comment.