From 284235beceeee8eaa6643bfe6d4f4ef47f379f50 Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 11:16:37 -0700 Subject: [PATCH 1/9] Store.groupby: pass extra kwargs and mark TODOs --- src/maggma/stores/advanced_stores.py | 4 ++-- src/maggma/stores/compound_stores.py | 1 + src/maggma/stores/gridfs.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/maggma/stores/advanced_stores.py b/src/maggma/stores/advanced_stores.py index cedce4b62..b8ef86f01 100644 --- a/src/maggma/stores/advanced_stores.py +++ b/src/maggma/stores/advanced_stores.py @@ -327,7 +327,7 @@ def groupby( lazy_substitute(criteria, self.reverse_aliases) return self.store.groupby( - keys=keys, properties=properties, criteria=criteria, skip=skip, limit=limit + keys=keys, properties=properties, criteria=criteria, skip=skip, limit=limit, sort=sort, ) def update(self, docs: Union[List[Dict], Dict], key: Union[List, str, None] = None): @@ -502,7 +502,7 @@ def groupby( ) return self.store.groupby( - keys=keys, properties=properties, criteria=criteria, skip=skip, limit=limit + keys=keys, properties=properties, criteria=criteria, skip=skip, limit=limit, sort=sort ) def update(self, docs: Union[List[Dict], Dict], key: Union[List, str, None] = None): diff --git a/src/maggma/stores/compound_stores.py b/src/maggma/stores/compound_stores.py index f7d7022a3..27b328412 100644 --- a/src/maggma/stores/compound_stores.py +++ b/src/maggma/stores/compound_stores.py @@ -251,6 +251,7 @@ def query( for d in agg: yield d + # TODO - sort kwarg is not passed anywhere def groupby( self, keys: Union[List[str], str], diff --git a/src/maggma/stores/gridfs.py b/src/maggma/stores/gridfs.py index 3122a0b1b..f7141654d 100644 --- a/src/maggma/stores/gridfs.py +++ b/src/maggma/stores/gridfs.py @@ -288,6 +288,7 @@ def distinct( return self._files_store.distinct(field=field, criteria=criteria) + # TODO - sort, skip, limit, and properties are not functional def groupby( self, keys: Union[List[str], str], From 51043a1648ff9f45210e8d2f84e2ec86a8e9f172 Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 11:45:40 -0700 Subject: [PATCH 2/9] MemoryStore: inherit parent groupby --- src/maggma/stores/mongolike.py | 47 ---------------------------------- 1 file changed, 47 deletions(-) diff --git a/src/maggma/stores/mongolike.py b/src/maggma/stores/mongolike.py index 7dd7b339d..60ed244bf 100644 --- a/src/maggma/stores/mongolike.py +++ b/src/maggma/stores/mongolike.py @@ -612,53 +612,6 @@ def __hash__(self): """Hash for the store""" return hash((self.name, self.last_updated_field)) - def groupby( - self, - keys: Union[List[str], str], - criteria: Optional[Dict] = None, - properties: Union[Dict, List, None] = None, - sort: Optional[Dict[str, Union[Sort, int]]] = None, - skip: int = 0, - limit: int = 0, - ) -> Iterator[Tuple[Dict, List[Dict]]]: - """ - Simple grouping function that will group documents - by keys. - - Args: - keys: fields to group documents - criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents - sort: Dictionary of sort order for fields. Keys are field names and - values are 1 for ascending or -1 for descending. - skip: number documents to skip - limit: limit on total number of documents returned - - Returns: - generator returning tuples of (key, list of elemnts) - """ - keys = keys if isinstance(keys, list) else [keys] - - if properties is None: - properties = [] - if isinstance(properties, dict): - properties = list(properties.keys()) - - data = [ - doc - for doc in self.query(properties=keys + properties, criteria=criteria) - if all(has(doc, k) for k in keys) - ] - - def grouping_keys(doc): - return tuple(get(doc, k) for k in keys) - - for vals, group in groupby(sorted(data, key=grouping_keys), key=grouping_keys): - doc = {} # type: Dict[Any,Any] - for k, v in zip(keys, vals): - set_(doc, k, v) - yield doc, list(group) - def __eq__(self, other: object) -> bool: """ Check equality for MemoryStore From 2fb2981ea751b2ce32d1303395289e69ae58765a Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 11:49:12 -0700 Subject: [PATCH 3/9] clarify docstrings on sort, skip, limit; add todos --- src/maggma/core/store.py | 4 ++-- src/maggma/stores/advanced_stores.py | 8 ++++---- src/maggma/stores/aws.py | 4 ++-- src/maggma/stores/compound_stores.py | 4 ++-- src/maggma/stores/file_store.py | 2 +- src/maggma/stores/gridfs.py | 4 ++-- src/maggma/stores/mongolike.py | 5 +++-- 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/maggma/core/store.py b/src/maggma/core/store.py index a62e61e66..dffbcc1f4 100644 --- a/src/maggma/core/store.py +++ b/src/maggma/core/store.py @@ -114,7 +114,7 @@ def query( Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -164,7 +164,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip diff --git a/src/maggma/stores/advanced_stores.py b/src/maggma/stores/advanced_stores.py index b8ef86f01..05d3e9d48 100644 --- a/src/maggma/stores/advanced_stores.py +++ b/src/maggma/stores/advanced_stores.py @@ -248,7 +248,7 @@ def query( Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -301,7 +301,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -459,7 +459,7 @@ def query( Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -488,7 +488,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip diff --git a/src/maggma/stores/aws.py b/src/maggma/stores/aws.py index 933caded0..8714270b5 100644 --- a/src/maggma/stores/aws.py +++ b/src/maggma/stores/aws.py @@ -175,7 +175,7 @@ def query( Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -267,7 +267,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip diff --git a/src/maggma/stores/compound_stores.py b/src/maggma/stores/compound_stores.py index 27b328412..c8bc70aaf 100644 --- a/src/maggma/stores/compound_stores.py +++ b/src/maggma/stores/compound_stores.py @@ -452,7 +452,7 @@ def query( Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -479,7 +479,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip diff --git a/src/maggma/stores/file_store.py b/src/maggma/stores/file_store.py index f78d5e876..31b540f3e 100644 --- a/src/maggma/stores/file_store.py +++ b/src/maggma/stores/file_store.py @@ -373,7 +373,7 @@ def query( # type: ignore Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. hint: Dictionary of indexes to use as hints for query optimizer. diff --git a/src/maggma/stores/gridfs.py b/src/maggma/stores/gridfs.py index f7141654d..1ecdadedc 100644 --- a/src/maggma/stores/gridfs.py +++ b/src/maggma/stores/gridfs.py @@ -211,7 +211,7 @@ def query( Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -306,7 +306,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip diff --git a/src/maggma/stores/mongolike.py b/src/maggma/stores/mongolike.py index 60ed244bf..1c7b78bbc 100644 --- a/src/maggma/stores/mongolike.py +++ b/src/maggma/stores/mongolike.py @@ -252,6 +252,7 @@ def distinct( return distinct_vals if distinct_vals is not None else [] + # TODO - sort, skip, and limit are not functional def groupby( self, keys: Union[List[str], str], @@ -268,7 +269,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -371,7 +372,7 @@ def query( # type: ignore Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. hint: Dictionary of indexes to use as hints for query optimizer. From c30d05c805643031e38b06c314800bd836400e99 Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 11:56:47 -0700 Subject: [PATCH 4/9] MongoStore.groupby: add tests for sort, skip, limit --- tests/stores/test_mongolike.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/stores/test_mongolike.py b/tests/stores/test_mongolike.py index 2cb33cab8..ec7c06db1 100644 --- a/tests/stores/test_mongolike.py +++ b/tests/stores/test_mongolike.py @@ -70,11 +70,21 @@ def test_mongostore_connect_reconnect(): def test_mongostore_query(mongostore): mongostore._collection.insert_one({"a": 1, "b": 2, "c": 3}) + mongostore._collection.insert_one({"a": 2, "b": 2, "c": 3}) + mongostore._collection.insert_one({"a": 4, "b": 5, "e": 6, "g": {"h": 1}}) assert mongostore.query_one(properties=["a"])["a"] == 1 assert mongostore.query_one(properties=["a"])["a"] == 1 assert mongostore.query_one(properties=["b"])["b"] == 2 assert mongostore.query_one(properties=["c"])["c"] == 3 + # the whole document should be returned when properties=None + assert all([d.get('a') for d in mongostore.query()]) + assert all([d.get('b') for d in mongostore.query()]) + + # test sort, skip, limit + assert len(list(mongostore.query(limit=2))) == 2 + assert len(list(mongostore.query(skip=1))) == 2 + assert list(mongostore.query(sort={"g": -1}))[0].get('e') def test_mongostore_count(mongostore): mongostore._collection.insert_one({"a": 1, "b": 2, "c": 3}) From fd14a6fef8191421b29e1397535d2371db5408bd Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 13:03:35 -0700 Subject: [PATCH 5/9] linting --- src/maggma/stores/advanced_stores.py | 14 ++++++++++++-- src/maggma/stores/mongolike.py | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/maggma/stores/advanced_stores.py b/src/maggma/stores/advanced_stores.py index 05d3e9d48..58959a01f 100644 --- a/src/maggma/stores/advanced_stores.py +++ b/src/maggma/stores/advanced_stores.py @@ -327,7 +327,12 @@ def groupby( lazy_substitute(criteria, self.reverse_aliases) return self.store.groupby( - keys=keys, properties=properties, criteria=criteria, skip=skip, limit=limit, sort=sort, + keys=keys, + properties=properties, + criteria=criteria, + skip=skip, + limit=limit, + sort=sort, ) def update(self, docs: Union[List[Dict], Dict], key: Union[List, str, None] = None): @@ -502,7 +507,12 @@ def groupby( ) return self.store.groupby( - keys=keys, properties=properties, criteria=criteria, skip=skip, limit=limit, sort=sort + keys=keys, + properties=properties, + criteria=criteria, + skip=skip, + limit=limit, + sort=sort, ) def update(self, docs: Union[List[Dict], Dict], key: Union[List, str, None] = None): diff --git a/src/maggma/stores/mongolike.py b/src/maggma/stores/mongolike.py index 1c7b78bbc..a49d91ad0 100644 --- a/src/maggma/stores/mongolike.py +++ b/src/maggma/stores/mongolike.py @@ -7,7 +7,7 @@ from pathlib import Path import yaml -from itertools import chain, groupby +from itertools import chain from socket import socket import warnings from typing import Any, Dict, Iterator, List, Optional, Tuple, Union From 373e56519651d326d8e4f834d25b6769ec387e5e Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 13:42:25 -0700 Subject: [PATCH 6/9] custom MontyStore.groupby and docstring fixes --- src/maggma/stores/mongolike.py | 51 ++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/maggma/stores/mongolike.py b/src/maggma/stores/mongolike.py index a49d91ad0..cf729b742 100644 --- a/src/maggma/stores/mongolike.py +++ b/src/maggma/stores/mongolike.py @@ -269,7 +269,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: fields to include in returned documents. By default, all fields are returned. + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -372,7 +372,7 @@ def query( # type: ignore Args: criteria: PyMongo filter for documents to search in - properties: fields to include in grouped documents. By default, only the 'id' field is returned. + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. hint: Dictionary of indexes to use as hints for query optimizer. @@ -895,6 +895,53 @@ def update(self, docs: Union[List[Dict], Dict], key: Union[List, str, None] = No search_doc = {key: d[key]} self._collection.replace_one(search_doc, d, upsert=True) + + # Moved this from MemoryStore b/c MontyDB does not implement aggregate() as + # of May 2022. See https://github.com/davidlatwe/montydb/issues/66 + def groupby( + self, + keys: Union[List[str], str], + criteria: Optional[Dict] = None, + properties: Union[Dict, List, None] = None, + sort: Optional[Dict[str, Union[Sort, int]]] = None, + skip: int = 0, + limit: int = 0, + ) -> Iterator[Tuple[Dict, List[Dict]]]: + """ + Simple grouping function that will group documents + by keys. + Args: + keys: fields to group documents + criteria: PyMongo filter for documents to search in + properties: fields to include in grouped documents. By default, only the 'id' field is returned. + sort: Dictionary of sort order for fields. Keys are field names and + values are 1 for ascending or -1 for descending. + skip: number documents to skip + limit: limit on total number of documents returned + Returns: + generator returning tuples of (key, list of elemnts) + """ + keys = keys if isinstance(keys, list) else [keys] + + if properties is None: + properties = [] + if isinstance(properties, dict): + properties = list(properties.keys()) + + data = [ + doc + for doc in self.query(properties=keys + properties, criteria=criteria) + if all(has(doc, k) for k in keys) + ] + + def grouping_keys(doc): + return tuple(get(doc, k) for k in keys) + + for vals, group in groupby(sorted(data, key=grouping_keys), key=grouping_keys): + doc = {} # type: Dict[Any,Any] + for k, v in zip(keys, vals): + set_(doc, k, v) + yield doc, list(group) def _find_free_port(address="0.0.0.0"): From 8b5309fbb9c2071a5da505cba8d9631f08af7ea0 Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 13:44:27 -0700 Subject: [PATCH 7/9] fix --- src/maggma/stores/mongolike.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maggma/stores/mongolike.py b/src/maggma/stores/mongolike.py index cf729b742..995d35948 100644 --- a/src/maggma/stores/mongolike.py +++ b/src/maggma/stores/mongolike.py @@ -7,7 +7,7 @@ from pathlib import Path import yaml -from itertools import chain +from itertools import chain, groupby from socket import socket import warnings from typing import Any, Dict, Iterator, List, Optional, Tuple, Union From 1d67292c5f621d00ada323a271697090318af325 Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Fri, 27 May 2022 13:49:04 -0700 Subject: [PATCH 8/9] lint --- src/maggma/stores/mongolike.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maggma/stores/mongolike.py b/src/maggma/stores/mongolike.py index 995d35948..8b2feadce 100644 --- a/src/maggma/stores/mongolike.py +++ b/src/maggma/stores/mongolike.py @@ -895,7 +895,7 @@ def update(self, docs: Union[List[Dict], Dict], key: Union[List, str, None] = No search_doc = {key: d[key]} self._collection.replace_one(search_doc, d, upsert=True) - + # Moved this from MemoryStore b/c MontyDB does not implement aggregate() as # of May 2022. See https://github.com/davidlatwe/montydb/issues/66 def groupby( From 42b110f45dd8d43188f962ed21ec55929ee5c464 Mon Sep 17 00:00:00 2001 From: Ryan Kingsbury Date: Wed, 14 Jun 2023 16:12:11 -0400 Subject: [PATCH 9/9] additional docstring clarifications --- src/maggma/core/store.py | 6 ++++-- src/maggma/stores/azure.py | 4 ++-- src/maggma/stores/compound_stores.py | 4 ++-- src/maggma/stores/shared_stores.py | 16 ++++++++-------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/maggma/core/store.py b/src/maggma/core/store.py index dffbcc1f4..b8dc0717f 100644 --- a/src/maggma/core/store.py +++ b/src/maggma/core/store.py @@ -193,10 +193,12 @@ def query_one( Queries the Store for a single document Args: - criteria: PyMongo filter for documents to search - properties: properties to return in the document + criteria: PyMongo filter for documents to search in + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. + skip: number documents to skip + limit: limit on total number of documents returned """ return next( self.query(criteria=criteria, properties=properties, sort=sort), None diff --git a/src/maggma/stores/azure.py b/src/maggma/stores/azure.py index 1c63a12b4..50f936df0 100644 --- a/src/maggma/stores/azure.py +++ b/src/maggma/stores/azure.py @@ -201,7 +201,7 @@ def query( Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -286,7 +286,7 @@ def groupby( Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip diff --git a/src/maggma/stores/compound_stores.py b/src/maggma/stores/compound_stores.py index 5413816ec..6e548e504 100644 --- a/src/maggma/stores/compound_stores.py +++ b/src/maggma/stores/compound_stores.py @@ -281,8 +281,8 @@ def query_one(self, criteria=None, properties=None, **kwargs): Get one document Args: - properties: properties to return in query - criteria: filter for matching + criteria: PyMongo filter for documents to search in + properties: fields to include in returned documents. By default, all fields are returned. kwargs: kwargs for collection.aggregate Returns: diff --git a/src/maggma/stores/shared_stores.py b/src/maggma/stores/shared_stores.py index 751241c8f..0cb661a27 100644 --- a/src/maggma/stores/shared_stores.py +++ b/src/maggma/stores/shared_stores.py @@ -102,7 +102,7 @@ def query(self, Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -162,7 +162,7 @@ def groupby(self, Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -200,8 +200,8 @@ def query_one(self, Queries the Store for a single document Args: - criteria: PyMongo filter for documents to search - properties: properties to return in the document + criteria: PyMongo filter for documents to search in + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. """ @@ -427,7 +427,7 @@ def query(self, Args: criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -496,7 +496,7 @@ def groupby(self, Args: keys: fields to group documents criteria: PyMongo filter for documents to search in - properties: properties to return in grouped documents + properties: fields to include in grouped documents. By default, only the 'id' field is returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. skip: number documents to skip @@ -534,8 +534,8 @@ def query_one(self, Queries the Store for a single document Args: - criteria: PyMongo filter for documents to search - properties: properties to return in the document + criteria: PyMongo filter for documents to search in + properties: fields to include in returned documents. By default, all fields are returned. sort: Dictionary of sort order for fields. Keys are field names and values are 1 for ascending or -1 for descending. """