Skip to content

Commit 3bcd0f1

Browse files
authored
Add ability to configure explain command options (#49)
1 parent 4514ef3 commit 3bcd0f1

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

README.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ To run explain on a command, first instantiate an ``ExplainableCollection`` from
9393
collection = client.db.products
9494
explain = ExplainableCollection(collection)
9595

96+
If you wish to configure the options for the explain command itself, pass
97+
them to the ``ExplainableCollection`` constructor like so::
98+
99+
explain = ExplainableCollection(collection, verbosity="queryPlanner",
100+
comment="I'm a comment")
101+
102+
For more information see the documentation for the explain_ command.
103+
104+
.. _explain: https://docs.mongodb.com/master/reference/command/explain/#dbcmd.explain.
105+
96106
Now you are ready to explain some commands. Remember that explaining a command does not execute it::
97107

98108
result = explain.update_one({"quantity": 1057, "category": "apparel"}, {"$set": {"reorder": True}})

pymongoexplain/explainable_collection.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,18 @@
2626

2727

2828
class ExplainableCollection():
29-
def __init__(self, collection):
29+
def __init__(self, collection, verbosity=None, comment=None):
3030
self.collection = collection
3131
self.last_cmd_payload = None
32+
self.verbosity = verbosity or "queryPlanner"
33+
self.comment = comment
3234

3335
def _explain_command(self, command):
3436
command_son = command.get_SON()
3537
explain_command = SON([("explain", command_son)])
36-
explain_command["verbosity"] = "queryPlanner"
38+
explain_command["verbosity"] = self.verbosity
39+
if self.comment:
40+
explain_command["comment"] = self.comment
3741
self.last_cmd_payload = command_son
3842
return self.collection.database.command(explain_command)
3943

test/test_collection.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
1615
import unittest
1716
import subprocess
1817
import os
@@ -28,6 +27,7 @@
2827
class CommandLogger(monitoring.CommandListener):
2928
def __init__(self):
3029
self.cmd_payload = {}
30+
3131
def started(self, event):
3232
self.cmd_payload = event.command
3333

@@ -37,6 +37,7 @@ def succeeded(self, event):
3737
def failed(self, event):
3838
pass
3939

40+
4041
class TestExplainableCollection(unittest.TestCase):
4142
def setUp(self) -> None:
4243
self.logger = CommandLogger()
@@ -217,6 +218,25 @@ def test_imports(self):
217218
from pymongoexplain import ExplainableCollection
218219
self.assertEqual(ExplainableCollection, ExplainCollection)
219220

221+
def test_verbosity(self):
222+
res = self.explain.find({})
223+
self.assertNotIn("executionStats", res)
224+
self.assertNotIn("allPlansExecution", res.get("executionStats", []))
225+
self.explain = ExplainCollection(self.collection, verbosity="executionStats")
226+
res = self.explain.find({})
227+
self.assertIn("executionStats", res)
228+
self.assertNotIn("allPlansExecution", res["executionStats"])
229+
self.explain = ExplainCollection(self.collection, verbosity="allPlansExecution")
230+
res = self.explain.find({})
231+
self.assertIn("executionStats", res)
232+
self.assertIn("allPlansExecution", res["executionStats"])
233+
234+
def test_comment(self):
235+
self.explain.find({})
236+
self.assertNotIn("comment", self.logger.cmd_payload)
237+
self.explain = ExplainCollection(self.collection, comment="comment")
238+
self.explain.find({})
239+
self.assertIn("comment", self.logger.cmd_payload)
220240

221241
if __name__ == '__main__':
222242
unittest.main()

0 commit comments

Comments
 (0)