<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 09:00:41 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>[JAVA-3888] BsonDocument.equals should consider field order</title>
                <link>https://jira.mongodb.org/browse/JAVA-3888</link>
                <project id="10006" key="JAVA">Java Driver</project>
                    <description>&lt;p&gt;When comparing two BsonDocuments using the BsonDocuments.equals() method the order of the fields does not seem to be considered.&lt;/p&gt;

&lt;p&gt;Currently {a:1, b:1}.equals({b:1,a:1})&#160; evaluates to true for BsonDocuments. For documents the expected behavior would be that documents are only considered to be same if the field order is the same.&#160;&lt;/p&gt;</description>
                <environment></environment>
        <key id="1541641">JAVA-3888</key>
            <summary>BsonDocument.equals should consider field order</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</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="kai.orend@mongodb.com">Kai Orend</reporter>
                        <labels>
                    </labels>
                <created>Fri, 13 Nov 2020 16:42:40 +0000</created>
                <updated>Wed, 30 Mar 2022 23:01:24 +0000</updated>
                                                                            <component>BSON</component>
                                        <votes>0</votes>
                                    <watches>6</watches>
                                                                                                                <comments>
                            <comment id="3501498" author="ross@10gen.com" created="Mon, 23 Nov 2020 08:04:42 +0000"  >&lt;p&gt;An alternative proposal could be to add a BsonDocument.strict() method to configure strict checking mode and check the flag in the equals() method.  &lt;/p&gt;

&lt;p&gt;That way recursive equality checks for sub documents etc can be handled easily and users could configure the setting globally via a custom BsonDocumentCodec.&lt;/p&gt;</comment>
                            <comment id="3501398" author="jeff.yemin" created="Mon, 23 Nov 2020 01:43:37 +0000"  >&lt;p&gt;I think I see now why we did it this way: it&apos;s because Document and BsonDocument implement the Map interface and as such they must obey the contract defined in the Map.equals documentation, which states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compares the specified object with this map for equality.  Returns &lt;tt&gt;true&lt;/tt&gt; if the given object is also a map and the two maps represent the same mappings.  More formally, two maps &lt;tt&gt;m1&lt;/tt&gt; and &lt;tt&gt;m2&lt;/tt&gt; represent the same mappings if &lt;tt&gt;m1.entrySet().equals(m2.entrySet())&lt;/tt&gt;.  &lt;br/&gt;
This ensures that the &lt;tt&gt;equals&lt;/tt&gt; method works properly across different implementations of the &lt;tt&gt;Map&lt;/tt&gt; interface.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;So I&apos;m convinced now that this is not a bug and should not be changed.&lt;/p&gt;

&lt;p&gt;We can consider adding an &lt;tt&gt;orderedEquals&lt;/tt&gt; method to both classes to handle this particular use case.&lt;/p&gt;</comment>
                            <comment id="3497921" author="jeff.yemin" created="Thu, 19 Nov 2020 16:34:14 +0000"  >&lt;p&gt;I tested both Document and BasicDBObject, and they both work the same as BsonDocument: they ignore key order.&#160; So we have been consistent.&lt;/p&gt;</comment>
                            <comment id="3492154" author="jeff.yemin" created="Mon, 16 Nov 2020 17:32:03 +0000"  >&lt;p&gt;I think it&apos;s clear that the current behavior is incorrect and could be considered a bug.  The concern is that changing the behavior of BsonDocument#equals to take field order into consideration could break existing applications.  And there is no way to warn people relying on the current behavior with deprecation warnings.  It would only be release notes.&lt;/p&gt;

&lt;p&gt;Maybe what we should do is introduce two new methods, one which takes order into account and one which does not.  And then update the documentation for equals to say that the behavior is &quot;undefined&quot; and may change in a future release.&lt;/p&gt;</comment>
                            <comment id="3492145" author="peter.williamson" created="Mon, 16 Nov 2020 17:27:56 +0000"  >&lt;p&gt;My 2c&apos;s worth: There&apos;s certainly a use case for a method that doesn&apos;t take order into account but given that order can be important equals should consider order. Perhaps contentsEquals could perform the current functionality.&lt;/p&gt;</comment>
                            <comment id="3491619" author="kai.orend" created="Mon, 16 Nov 2020 14:45:58 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=ross.lawley&quot; class=&quot;user-hover&quot; rel=&quot;ross.lawley&quot;&gt;ross.lawley&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;

&lt;p&gt;on the server it depends. In you example of a find query the filter is using an implicit and. However in cases where you filter on a whole document the server would use a binary comparison on the BSON representation:&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;

&lt;p&gt;&#160;&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;   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;db.test.insertOne({ d : {a:&lt;/span&gt;&lt;span style=&quot;color: #009900; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;1&lt;/span&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;, b:&lt;/span&gt;&lt;span style=&quot;color: #009900; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;2&lt;/span&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;}})&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&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;   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;&#160;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&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;   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;db.test.count({ d : {b:&lt;/span&gt;&lt;span style=&quot;color: #009900; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;2&lt;/span&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;, b:&lt;/span&gt;&lt;span style=&quot;color: #009900; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;1&lt;/span&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;}}) &lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&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;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: #009900; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;0&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&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-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;&#160;&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;&#160;&lt;/p&gt;

&lt;p&gt;However the context where I was hitting this issue was when comparing index definitions where the order is definitely important. And the BsonDocument equals should probably behave the same way as the one from the Document class.&#160;&#160;&lt;/p&gt;

&lt;p&gt;Kai&lt;/p&gt;</comment>
                            <comment id="3491291" author="ross@10gen.com" created="Mon, 16 Nov 2020 09:43:46 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=kai.orend&quot; class=&quot;user-hover&quot; rel=&quot;kai.orend&quot;&gt;kai.orend&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;What are your reasons for wanting to test insertion order?  Just to note the server considers such documents as equal:&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;   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;MongoDB Enterprise &amp;gt; db.test.insert({b: 1, a: 1})&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&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;   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;WriteResult({ &quot;nInserted&quot; : 1 })&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&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;   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;MongoDB Enterprise &amp;gt; db.test.find({a: 1, b: 1})&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&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-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;{ &quot;_id&quot; : ObjectId(&quot;5fb2484503eb536ee8a70ceb&quot;), &quot;b&quot; : 1, &quot;a&quot; : 1 }&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;From the &lt;a href=&quot;https://docs.mongodb.com/manual/reference/bson-type-comparison-order/#objects&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;documented comparison / sort order&lt;/a&gt; for bson objects is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;MongoDB&#8217;s comparison of BSON objects uses the following order:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Recursively compare key-value pairs in the order that they appear within the BSON object.&lt;/li&gt;
	&lt;li&gt;Compare the key field names.&lt;/li&gt;
	&lt;li&gt;If the key field names are equal, compare the field values.&lt;/li&gt;
	&lt;li&gt;If the field values are equal, compare the next key/value pair (return to step 1). An object without further pairs is less than an object with further pairs.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;So even the server doesn&apos;t appear to follow the ordering of the fields from within the Bson document.&lt;/p&gt;

&lt;p&gt;Ross&lt;/p&gt;</comment>
                    </comments>
                    <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_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hr69xb:</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>