<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 08:25:47 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[DRIVERS-2518] Add rationale for why the filter parameter is required for countDocuments</title>
                <link>https://jira.mongodb.org/browse/DRIVERS-2518</link>
                <project id="10980" key="DRIVERS">Drivers</project>
                    <description>&lt;p&gt;When the countDocuments API was added I believe the intention was to make the filter parameter required, that is &lt;tt&gt;coll.countDocuments()&lt;/tt&gt; is not allowed, it has to be  &lt;tt&gt;coll.countDocuments({})&lt;/tt&gt;. However I can&apos;t find any such rationale in the spec itself. We should add rationale for why the filter parameter is required for countDocuments and perhaps even add a spec test that calling countDocuments without a filter will raise an error.&lt;/p&gt;</description>
                <environment></environment>
        <key id="2210023">DRIVERS-2518</key>
            <summary>Add rationale for why the filter parameter is required for countDocuments</summary>
                <type id="3" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14718&amp;avatarType=issuetype">Task</type>
                                            <priority id="10300" iconUrl="https://jira.mongodb.org/images/icons/priorities/medium.svg">Unknown</priority>
                        <status id="10038" iconUrl="https://jira.mongodb.org/images/icons/subtask.gif" description="">Backlog</status>
                    <statusCategory id="2" key="new" colorName="default"/>
                                    <resolution id="-1">Unresolved</resolution>
                                        <assignee username="-1">Unassigned</assignee>
                                    <reporter username="shane.harvey@mongodb.com">Shane Harvey</reporter>
                        <labels>
                    </labels>
                <created>Wed, 14 Dec 2022 00:15:46 +0000</created>
                <updated>Mon, 26 Jun 2023 13:53:45 +0000</updated>
                                                                <component>CRUD</component>
                                        <votes>0</votes>
                                    <watches>3</watches>
                                                                                                                <comments>
                            <comment id="5065862" author="shane.harvey" created="Mon, 19 Dec 2022 23:14:43 +0000"  >&lt;p&gt;Thanks for the deep dive &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jmikola%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jmikola@mongodb.com&quot;&gt;jmikola@mongodb.com&lt;/a&gt;. In that case let&apos;s not add a test for this behavior since it would be a breaking change in some drivers. Let&apos;s just make the rationale clear in the spec and let existing drivers stay as they are. &lt;/p&gt;</comment>
                            <comment id="5057278" author="jmikola@gmail.com" created="Thu, 15 Dec 2022 14:12:58 +0000"  >&lt;p&gt;Writing this was a fun trip down memory lane. I&apos;ll address the comments above in the order they were written.&lt;/p&gt;

&lt;h3&gt;&lt;a name=&quot;Historicalevidencefor%7B%7Bfilter%7D%7DbeingarequiredparameterforallCRUDAPIs&quot;&gt;&lt;/a&gt;Historical evidence for &lt;tt&gt;filter&lt;/tt&gt; being a required parameter for all CRUD APIs&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;AFAICT the spec doesn&apos;t say that find requires a filter, python supports coll.find() for example as do other drivers.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I was basing that on the method declaration:&lt;/p&gt;

&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;find(filter: Document, options: Optional&amp;lt;FindOptions&amp;gt;): Iterable&amp;lt;Document&amp;gt;;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;I was able to dig up some old comments supporting the historical justification I alluded to above. &lt;a href=&quot;https://jira.mongodb.org/browse/SPEC-76?focusedCommentId=754020&amp;amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-754020&quot; class=&quot;external-link&quot; rel=&quot;nofollow&quot;&gt;This comment from SPEC-76&lt;/a&gt; explains how we ended up requiring explicit &lt;tt&gt;filter&lt;/tt&gt; arguments:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All criteria (now filter) will be required in every operation per Eliot.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;And &lt;a href=&quot;https://jira.mongodb.org/browse/SPEC-86?focusedCommentId=754022&amp;amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-754022&quot; class=&quot;external-link&quot; rel=&quot;nofollow&quot;&gt;this comment from SPEC-86&lt;/a&gt; provides some more context on how to interpret the API declarations:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The only positional arguments allowed are the required arguments. All other arguments must either be named or part of the options hash&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This is also why all spec tests for &lt;tt&gt;find&lt;/tt&gt;, &lt;tt&gt;count&lt;/tt&gt;, and &lt;tt&gt;distinct&lt;/tt&gt; operations specify a &lt;tt&gt;filter&lt;/tt&gt; argument, even if it&apos;s just an empty document &amp;#8211; not just in the CRUD spec but in derivative specs such as retryable reads as well. There is one reference in the CRUD spec where &lt;tt&gt;collection.find({})&lt;/tt&gt; is called without an argument but it&apos;s in the definition for &quot;Iterable&quot; so I wouldn&apos;t consider that authoritative (and it was likely just intended to be a concise reference to the operation name).&lt;/p&gt;

&lt;h3&gt;&lt;a name=&quot;The%7B%7Bfilter%7D%7DparameterforcountrelatedAPIs&quot;&gt;&lt;/a&gt;The &lt;tt&gt;filter&lt;/tt&gt; parameter for count-related APIs&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;estimateDocumentCount() uses the count command to get the total document count from collection metadata, a fast operation. countDocuments({}) uses aggregation to count the documents, a comparatively slow operation. The point of requiring the empty document was to re-enforce what the method actually does and what it is for, returning the count of a query.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;By design, estimateDocumentCount() cannot take a &lt;tt&gt;filter&lt;/tt&gt; parameter because it relies on the &lt;tt&gt;count&lt;/tt&gt; command&apos;s behavior to return an estimated count from collection metadata in the absence of a query filter.&lt;/p&gt;

&lt;p&gt;If there was an actual rationale for requiring &lt;tt&gt;filter&lt;/tt&gt; on &lt;tt&gt;countDocuments()&lt;/tt&gt; independent of maintaining consistency with existing CRUD APIs, I could find no record of it. There was a patch in the &lt;a href=&quot;https://mongodbcr.appspot.com/209290001/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;original code review&lt;/a&gt; titled &quot;Make it clear that filter is a required argument&quot; but no comments leading up to it. There likewise isn&apos;t any mention about this in the &lt;a href=&quot;https://docs.google.com/document/d/1xxuJ7bObDF21biI3qbC2hO0SBMw74DN0ZNB5NMJ6l_8/edit#heading=h.sye21yee6q34&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;scope doc&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;In almost all cases someone calling countDocuments with an empty filter would be better served by estimatedDocumentCount.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;No argument there.&lt;/p&gt;

&lt;h3&gt;&lt;a name=&quot;Havingsaidthat...&quot;&gt;&lt;/a&gt;Having said that...&lt;/h3&gt;

&lt;p&gt;As Shane pointed out, Python and probably most drivers do not require &lt;tt&gt;filter&lt;/tt&gt; parameters for various CRUD methods. We can say this is because we priortize BC over spec compliance, but I doubt any driver has bothered to change that in a major version bump. Likewise, drivers written &lt;em&gt;after&lt;/em&gt; the CRUD spec don&apos;t seem to require &lt;tt&gt;filter&lt;/tt&gt; either (e.g. &lt;a href=&quot;https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.find&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Rust&lt;/a&gt;). In fact, Rust&apos;s &lt;a href=&quot;https://docs.rs/mongodb/latest/mongodb/struct.Collection.html#method.count_documents&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;tt&gt;count_documents()&lt;/tt&gt;&lt;/a&gt; method also has an optional &lt;tt&gt;filter&lt;/tt&gt; and it looks like &lt;a href=&quot;https://mongodb.github.io/node-mongodb-native/4.12/classes/Collection.html#countDocuments&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Node does as well&lt;/a&gt;. In flagrant disregard for the CRUD spec, I historically allowed optional filters for all read-only CRUD methods in PHPLIB &amp;#8211; and didn&apos;t consider any reason not to continue doing so when implementing &lt;tt&gt;countDocuments()&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;I won&apos;t object if someone wants to add a rationale to the spec, but I don&apos;t think it serves much purpose if we&apos;re missing rationale for other methods like &lt;tt&gt;find()&lt;/tt&gt; and &lt;tt&gt;distinct()&lt;/tt&gt; &amp;#8211; and I&apos;m not sure what else we might say for those at this point other than &quot;This is what Eliot wanted in 2014&quot;. And even if we do that, it doesn&apos;t change the fact that at least a handful of drivers allow it to be optional anyway.&lt;/p&gt;</comment>
                            <comment id="5055611" author="shane.harvey" created="Wed, 14 Dec 2022 20:06:33 +0000"  >&lt;p&gt;AFAICT the spec doesn&apos;t say that find requires a filter, python supports coll.find() for example as do other drivers.&lt;/p&gt;</comment>
                            <comment id="5053342" author="jmikola@gmail.com" created="Wed, 14 Dec 2022 03:58:34 +0000"  >&lt;p&gt;I&apos;m not going to jump through the git history but I imagine this is related to &lt;tt&gt;find()&lt;/tt&gt; also requiring a &lt;tt&gt;filter&lt;/tt&gt; document &amp;#8211; and the justification for that goes likely back to the original draft of the CRUD spec (so the only rationale might be in an old Google Doc comment thread).&lt;/p&gt;

&lt;p&gt;IMO, it only makes sense to do so for write methods where a default filter could make it possible to fat-finger a deleteMany or updateMany. I&apos;ve never agreed with the &lt;tt&gt;find()&lt;/tt&gt; method requiring a filter parameter and PHP has historically never required it (in the interest of BC).&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                                                <inwardlinks description="is related to">
                                        <issuelink>
            <issuekey id="555790">DRIVERS-501</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                            <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                    <customfield id="customfield_10951" key="com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons">
                        <customfieldname>Driver Changes</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10940"><![CDATA[Not Needed]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|i158a0:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        </customfields>
    </item>
</channel>
</rss>