<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 03:07: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>[SERVER-5030] Document equality should be independent of field insertion order</title>
                <link>https://jira.mongodb.org/browse/SERVER-5030</link>
                <project id="10000" key="SERVER">Core Server</project>
                    <description>&lt;p&gt;Equality of documents should not depend on the order of the fields.  The following documents should be considered equal:&lt;/p&gt;

{a: 1, b: 2}
{b: 2, a: 1}

&lt;p&gt;The above documents would be considered the same document for purposes of unique indexes, and would be considered a match for searching.&lt;/p&gt;

&lt;p&gt;This allows documents to map much more naturally to the native, built-in dictionary types in various languages.  Most native dictionary types don&apos;t preserve order, and builtin dictionary types that support equality (Python, Ruby) don&apos;t compare insertion order.  Ruby, which does explicitly preserve insertion order, also still does not consider insertion order for equality; {:a=&amp;gt;1, :b=&amp;gt;2} == {:b=&amp;gt;2, :a=&amp;gt;1} is true.&lt;/p&gt;

&lt;p&gt;This would reduce the need to use inconvenient non-builtin dictionary types, and align documents to typical expectations of dictionary types.&lt;/p&gt;

&lt;p&gt;Note: this is not a recommendation to stop preserving insertion order.  Although I don&apos;t find that useful, it&apos;s not obviously harmful, and it should be possible to do both efficiently.&lt;/p&gt;

&lt;p&gt;Additional discussion at &lt;a href=&quot;http://groups.google.com/group/mongodb-user/browse_thread/thread/c908e572d6e89c49&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://groups.google.com/group/mongodb-user/browse_thread/thread/c908e572d6e89c49&lt;/a&gt;.&lt;/p&gt;</description>
                <environment></environment>
        <key id="31149">SERVER-5030</key>
            <summary>Document equality should be independent of field insertion order</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="4" iconUrl="https://jira.mongodb.org/images/icons/priorities/minor.svg">Minor - P4</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="backlog-query-execution">Backlog - Query Execution</assignee>
                                    <reporter username="glenn">Glenn Maynard</reporter>
                        <labels>
                            <label>bson2</label>
                            <label>query_triage</label>
                    </labels>
                <created>Tue, 21 Feb 2012 21:14:38 +0000</created>
                <updated>Tue, 6 Dec 2022 05:36:08 +0000</updated>
                                                                            <component>Querying</component>
                                        <votes>9</votes>
                                    <watches>30</watches>
                                                                                                                <comments>
                            <comment id="437714" author="daniel.sinclair@nupe.com" created="Tue, 8 Oct 2013 21:44:59 +0000"  >&lt;p&gt;I totally agree. Don&apos;t get me wrong, I &lt;b&gt;don&apos;t&lt;/b&gt; want to have order dependent&lt;br/&gt;
code and right now it seems in conflict that the driver&apos;s don&apos;t preserve&lt;br/&gt;
order whereas the DB is order-important. As a conflict, it&apos;s either a&lt;br/&gt;
driver bug/oversight or a DB one.&lt;/p&gt;

&lt;p&gt;Since it might hamper DB performance, and we can&apos;t guarantee order in the&lt;br/&gt;
languages, it sounds like most practical solution would be to consistently&lt;br/&gt;
order fields in all drivers and therefore by convention in the DB and&lt;br/&gt;
elsewhere.&lt;/p&gt;

&lt;p&gt;Either way - you&apos;re absolutely right, it&apos;s a real issue that needs to be&lt;br/&gt;
addressed.&lt;/p&gt;


</comment>
                            <comment id="436504" author="glenn" created="Mon, 7 Oct 2013 13:36:00 +0000"  >&lt;p&gt;The issue isn&apos;t that it&apos;s completely impossible to preserve dictionary order.  The problem is that it&apos;s easy to get lurking bugs in day-to-day user code.  For example, it&apos;s easy to write &lt;/p&gt;
{&quot;a&quot;: 1, &quot;b&quot;: 2}
&lt;p&gt; in Python, and without realizing it depend on the key order that Python&apos;s hashing happens to give you.  You&apos;ll often get the same key order every time, so everything seems to work, but it&apos;s actually depending on the hash behavior of your current version of Python, so it&apos;ll break if Python changes its hash algorithm, and it won&apos;t work in any language except Python.  I&apos;ve done this myself without noticing what I was doing, even though I know about it, and it&apos;s very easy for this to slip through testing.&lt;/p&gt;

&lt;p&gt;It&apos;s also painful to not be able to use dictionary literals in most languages.&lt;/p&gt;

&lt;p&gt;It doesn&apos;t mean that it can&apos;t be done at all; drivers could easily guarantee a particular order in their BSON handling if that was wanted.  The issue here is about sanity of user code, but the drivers can handle this however they want internally.&lt;/p&gt;</comment>
                            <comment id="436464" author="daniel.sinclair@nupe.com" created="Mon, 7 Oct 2013 09:54:47 +0000"  >&lt;p&gt;Isn&apos;t the main issue that most languages don&apos;t preserve dictionary order?&lt;br/&gt;
If true, how would you manage that in the driver if field order remains&lt;br/&gt;
important? Presumably some mappings couldn&apos;t be supported?&lt;/p&gt;


</comment>
                            <comment id="436256" author="daniel.sinclair@nupe.com" created="Sat, 5 Oct 2013 18:07:58 +0000"  >&lt;p&gt;So can you ensure a particular field order from every language ? I&apos;m&lt;br/&gt;
thinking specifically about dictionary mappings here&lt;/p&gt;


</comment>
                            <comment id="436245" author="eliot" created="Sat, 5 Oct 2013 16:52:06 +0000"  >&lt;p&gt;Glenn, yes, unless in bson 2 we declare all bson document fields are sorted by key name.&lt;/p&gt;

&lt;p&gt;Or say that bson 2 documents compare differently than 1 docs in this regard.&lt;/p&gt;</comment>
                            <comment id="436244" author="glenn" created="Sat, 5 Oct 2013 16:49:48 +0000"  >&lt;p&gt;Just to be clear, James&apos;s idea of updating subdocuments in-place is what would require BSON format changes, not the change this bug is about.&lt;/p&gt;</comment>
                            <comment id="436241" author="glenn" created="Sat, 5 Oct 2013 16:35:23 +0000"  >&lt;p&gt;James: That sounds like it would require significant changes to the BSON data format, so it doesn&apos;t sound like an optimization that would ever happen.  (Even simpler fixes, like not storing the index of each item in BSON arrays, are hard to get any traction on, since changing the BSON format affects every driver and probably third-party software.)&lt;/p&gt;</comment>
                            <comment id="436228" author="jblackburn" created="Sat, 5 Oct 2013 15:18:30 +0000"  >&lt;blockquote&gt;
&lt;p&gt;In 2.6, we&apos;re actually changing the update code so that it never re-orders, which should guarantee that the order that documents come in stay in that order.&lt;br/&gt;
If we were going to change, to make things reasonably efficient, we&apos;d probably have to sort all keys so that comparison are fast.&lt;br/&gt;
I&apos;m not sure how people would feel about that, opinions here?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I&apos;ve got one strong counter-argument to this: efficiency of small updates to large documents.  As things currently stand updating a document dirties all the document&apos;s pages, even if only a single fixed-length field is changed.  For arrays this is worse: ss the document size changes subsequent fields move.  This means multi-document updates can cause significant unnecessary I/O.&lt;/p&gt;

&lt;p&gt;If instead mutated fields, and variably-sized fields were stored/moved to the end of the document then the update code could be easily optimised to touch just the page(s) containing the mutated fields at the end of the document.  If this happened dynamically during update then mongo would be much friendlier to the underlying storage.&lt;/p&gt;</comment>
                            <comment id="435891" author="daniel.sinclair@nupe.com" created="Fri, 4 Oct 2013 17:03:49 +0000"  >&lt;p&gt;Actually, you&apos;re correct about JS - I misspoke, I guess I was just thinking&lt;br/&gt;
of the way my application code manipulates fields in collections. The order&lt;br/&gt;
isn&apos;t considered important enough to preserve and once it&apos;s been through a&lt;br/&gt;
few constructor and mapper functions I wouldn&apos;t like to guarantee that&lt;br/&gt;
fields were in a specific order either.&lt;/p&gt;

&lt;p&gt;Your point about the drivers I agree with. Sorting is OK, but I&apos;d much&lt;br/&gt;
rather NOT have order dependency, and I don&apos;t think it&apos;s currently enforced&lt;br/&gt;
anywhere except the DB, which is unfortunate.&lt;/p&gt;

&lt;p&gt;Indexes though was how I first found this thread. I wanted to use an object&lt;br/&gt;
field index and I just wanted to make sure that it would work the way I&lt;br/&gt;
expected - it doesn&apos;t. I don&apos;t think you can make an exception for indexes,&lt;br/&gt;
they&apos;re would surely have to work the same way, no?&lt;/p&gt;

&lt;p&gt;If we can&apos;t guarantee order of fields from the client, then the DB needs to&lt;br/&gt;
able to cope whether indexed or not. I appreciate however that it&apos;s&lt;br/&gt;
probably not as efficient to build an index that&apos;s order independent, which&lt;br/&gt;
is why I floated sorting the field order. In order to make indexes work&lt;br/&gt;
without a consistent, predictable, sorted field order would be to generate&lt;br/&gt;
the indexes with sorted fields and query indexed fields with sorted fields.&lt;br/&gt;
That sounds like it would suck, so the alternative would be to enforce a&lt;br/&gt;
predictable order always, and the only way I can see a driver can guarantee&lt;br/&gt;
that is by alphanumeric sort, unless there&apos;s something else I&apos;ve not&lt;br/&gt;
considered?&lt;/p&gt;


</comment>
                            <comment id="435888" author="eliot" created="Fri, 4 Oct 2013 17:00:05 +0000"  >&lt;p&gt;Glenn, correct.&lt;/p&gt;

&lt;p&gt;JavaScript maintains order and has no notion of document equality.  &lt;br/&gt;
That&apos;s why we originally went this way, to maintain compatibility with javascript.&lt;/p&gt;

&lt;p&gt;Daniel, all the drivers support building order dependent documents, but agree its probably not ideal.&lt;/p&gt;

&lt;p&gt;Its just not totally clear what the right path forward is.&lt;/p&gt;

&lt;p&gt;Going to move this ticket to put it near the top of things to think about.&lt;/p&gt;</comment>
                            <comment id="435872" author="glenn" created="Fri, 4 Oct 2013 16:46:18 +0000"  >&lt;p&gt;Sorting the keys is fine.  In most languages, dictionaries are inherently unordered, so having keys come back in a different order is OK.  I prefer this, actually, since it helps guarantee that I won&apos;t accidentally write code that depends on the ordering behavior of a particular language/driver.&lt;/p&gt;

&lt;p&gt;For people depending on order-sensitivity or order-preservation, an option would be to make this a collection-level flag to enable and disable this.  It would probably be OK if changing this flag after collection creation wasn&apos;t allowed, so supporting migrating the data wouldn&apos;t be required.  For example, since this flag would change compound shard keys, this restriction means upgrading wouldn&apos;t cause lots of documents to be moved across shards.  On upgrade, set this flag for all existing collections; users would need to copy data to a new collection if they want to migrate existing data.&lt;/p&gt;

&lt;p&gt;system.indexes does depend on order-preservation, so that collection could use that flag, avoiding the need to restructure it.&lt;/p&gt;

&lt;p&gt;&amp;gt; fundamentally broken. By not supporting equivalence the way JavaScript does&lt;/p&gt;

&lt;p&gt;Actually, JavaScript is one of the only languages I&apos;ve used that &lt;b&gt;does&lt;/b&gt; always preserve dictionary order.  Every other major language I&apos;ve used doesn&apos;t unless you jump hoops.  (I don&apos;t think JS has any concept of object equality.)&lt;/p&gt;
</comment>
                            <comment id="435864" author="daniel.sinclair@nupe.com" created="Fri, 4 Oct 2013 16:39:48 +0000"  >&lt;p&gt;Presumably you can have a &quot;strict&quot; or &quot;fast&quot; mode for those that don&apos;t want&lt;br/&gt;
to switch. Sorting would be valid, since there are no guarantees on order&lt;br/&gt;
already, but I think the impact of NOT having dictionary equivalence is&lt;br/&gt;
fundamentally broken. By not supporting equivalence the way JavaScript does&lt;br/&gt;
and many other languages/drivers is surely more of a risk. It means that&lt;br/&gt;
any slight change in layout of a language level dictionary could cause hard&lt;br/&gt;
to find, catastrophic but possibly intermittent errors in almost any query.&lt;br/&gt;
I&apos;m using the C# driver and to be honest I&apos;m astonished I&apos;ve not run into&lt;br/&gt;
this before now.&lt;/p&gt;

&lt;p&gt;If we can&apos;t guarantee on the order of fields out of the driver (and I don&apos;t&lt;br/&gt;
think we should BTW, JavaScript doesn&apos;t expect that) then surely it&apos;s a&lt;br/&gt;
house of cards waiting to fall over since you can&apos;t safely construct any&lt;br/&gt;
nested object query reliably at all?&lt;/p&gt;

&lt;p&gt;If you were going to keep to an order, then I&apos;d have said sorted&lt;br/&gt;
alphabetically would be a good option rather than the order presented, but&lt;br/&gt;
you&apos;d have to enforce that in all the drivers since the language may not be&lt;br/&gt;
able to consider that. Sorting fields alphanumerically is a good option if&lt;br/&gt;
you want to hash them.&lt;/p&gt;

&lt;p&gt;I&apos;d vote firstly for equivalence &lt;/p&gt;
{a:1,b:2}
&lt;p&gt; === &lt;/p&gt;
{b:2,a:1}
&lt;p&gt;, failing that,&lt;br/&gt;
driver enforced alphanumerical, but I don&apos;t think it can remain as it is. I&lt;br/&gt;
think we gotta just take the hit soon before people start running into&lt;br/&gt;
scary production issues.&lt;/p&gt;


</comment>
                            <comment id="435842" author="eliot" created="Fri, 4 Oct 2013 16:13:51 +0000"  >&lt;p&gt;We&apos;ve gone back and forth on this one a lot over the last couple of years.&lt;/p&gt;

&lt;p&gt;Many strong opinions on both sides.&lt;/p&gt;

&lt;p&gt;In 2.6, we&apos;re actually changing the update code so that it never re-orders, which should guarantee that the order that documents come in stay in that order.&lt;/p&gt;

&lt;p&gt;If we were going to change, to make things reasonably efficient, we&apos;d probably have to sort all keys so that comparison are fast.&lt;br/&gt;
I&apos;m not sure how people would feel about that, opinions here?&lt;/p&gt;

&lt;p&gt;Also not sure how to migrate if we did want to change.&lt;/p&gt;</comment>
                            <comment id="435703" author="daniel.sinclair@nupe.com" created="Fri, 4 Oct 2013 12:12:13 +0000"  >&lt;p&gt;I also think this is a problem;&lt;/p&gt;

&lt;p&gt;db.xxx.drop();&lt;br/&gt;
db.xxx.insert({id: {bar:2, foo:1}});&lt;br/&gt;
db.xxx.insert({id: {foo:1, bar:2}}); // should be equivalent&lt;br/&gt;
db.xxx.find({   id: {bar:2, foo:1}}); // only returns the first one&lt;/p&gt;

&lt;p&gt;&quot;MongoDB does not make guarantees regarding the order of fields in a BSON document. Drivers and MongoDB will reorder the fields of a documents upon insertion and following updates.&quot;&lt;br/&gt;
&lt;a href=&quot;http://docs.mongodb.org/manual/core/document/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://docs.mongodb.org/manual/core/document/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which is clearly only true for top-level fields. However, id is &lt;b&gt;also&lt;/b&gt; considered a BsonDocument.&lt;/p&gt;</comment>
                            <comment id="168937" author="glenn" created="Thu, 27 Sep 2012 20:27:58 +0000"  >&lt;p&gt;It happens everywhere subdocuments are compared against each other; from what I recall it&apos;s actually just a byte-for-byte comparison of the BSON data, without even looking at its contents.&lt;/p&gt;</comment>
                            <comment id="168930" author="calebjones" created="Thu, 27 Sep 2012 20:18:08 +0000"  >&lt;p&gt;Note that this occurs with $addToSet:&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;&amp;gt; db.test.insert({ &quot;_id&quot; : 1, &quot;array&quot; : [ {&quot;f1&quot; : 1, &quot;f2&quot;, 2} ] })&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;&amp;gt; db.test.find()&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;{ &quot;_id&quot; : 1, &quot;array&quot; : [ {&quot;f1&quot; : 1, &quot;f2&quot;, 2} ] }&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;&amp;gt; db.test.update({ &quot;_id&quot; : 1 }, { &quot;$addToSet&quot; : { &quot;array&quot; : { &quot;f2&quot; : 2, &quot;f1&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;&amp;gt; db.test.find()&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; : 1, &quot;array&quot; : [ {&quot;f1&quot; : 1, &quot;f2&quot;, 2}, { &quot;f2&quot; : 2, &quot;f1&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;</comment>
                            <comment id="165527" author="glenn" created="Tue, 18 Sep 2012 14:58:11 +0000"  >&lt;p&gt;(Why is a bugtracker hideously image-izing smileys?  Who seriously thought that was a good idea?)&lt;/p&gt;</comment>
                            <comment id="165525" author="glenn" created="Tue, 18 Sep 2012 14:56:44 +0000"  >&lt;p&gt;Because it doesn&apos;t solve the problem.  &lt;img class=&quot;emoticon&quot; src=&quot;https://jira.mongodb.org/images/icons/emoticons/smile.png&quot; height=&quot;16&quot; width=&quot;16&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/p&gt;</comment>
                            <comment id="165507" author="root" created="Tue, 18 Sep 2012 14:21:12 +0000"  >&lt;p&gt;Hum ... when you say : &quot;For example, if you insert a record manually in the shell, you need to remember to apply the same ordering&quot; it&apos;s true, with AND without my solution ...&lt;/p&gt;</comment>
                            <comment id="165496" author="glenn" created="Tue, 18 Sep 2012 14:08:29 +0000"  >&lt;p&gt;That&apos;s brittle: you have to make sure you apply something like this in every place you access the database.  For example, if you insert a record manually in the shell, you need to remember to apply the same ordering.  If you forget, or get it wrong (eg. if the sort order isn&apos;t identical for Unicode characters), you get subtle breakage.  Avoiding brittleness is a major reason to want this in the first place.&lt;/p&gt;

&lt;p&gt;This also doesn&apos;t work when setting subkeys of an object, rather than replacing the whole object.&lt;/p&gt;

&lt;p&gt;The only way I can think of to fix this properly is a collection-level flag.&lt;/p&gt;</comment>
                            <comment id="165400" author="root" created="Tue, 18 Sep 2012 08:44:26 +0000"  >&lt;p&gt;Or a SON ctor from a dict, something like :&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;&amp;nbsp;&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;from operator import itemgetter&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;&amp;nbsp;&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;def dict2SON(values):               &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;    if not isinstance(values, dict):&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;        return values                        &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;    return SON(sorted([(key, dict2SON(value))&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;                       for key, value     &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;                       in values.items()],&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;                      key=itemgetter(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;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;


&lt;p&gt;Does it seems a good idea ?&lt;/p&gt;</comment>
                            <comment id="165399" author="root" created="Tue, 18 Sep 2012 08:33:16 +0000"  >&lt;p&gt;And what about providing a example code of an &quot;Ordering key SON manipulator&quot; in drivers ?&lt;br/&gt;
It&apos;s not intrusive, and solve the problem for those who want to use it.&lt;/p&gt;</comment>
                            <comment id="164084" author="glenn" created="Thu, 13 Sep 2012 18:22:34 +0000"  >&lt;p&gt;It would have been good to do that from the start, but unfortunately, MongoDB currently guarantees preservation of dictionary order.  Applications probably depends on that, so normalizing dictionaries would probably cause backwards-compatibility issues.&lt;/p&gt;</comment>
                            <comment id="164077" author="root" created="Thu, 13 Sep 2012 18:10:15 +0000"  >&lt;p&gt;I got an idea about this problem, what about ordering by key, server side, at insert time ? It would hide the &quot;order sensitive&quot; problem, leaving a natural, order insensitive database, without dropping any performance nor touching any loc of the storage engine ...&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10011">
                    <name>Depends</name>
                                                                <inwardlinks description="is depended on by">
                                                        </inwardlinks>
                                    </issuelinktype>
                            <issuelinktype id="10010">
                    <name>Duplicate</name>
                                                                <inwardlinks description="is duplicated by">
                                        <issuelink>
            <issuekey id="267475">SERVER-22817</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="264078">SERVER-22529</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="409526">SERVER-30392</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                            <outwardlinks description="related to">
                                        <issuelink>
            <issuekey id="417303">SERVER-30705</issuekey>
        </issuelink>
                            </outwardlinks>
                                                                <inwardlinks description="is related to">
                                        <issuelink>
            <issuekey id="404930">SERVER-30197</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                            <attachment id="33331" name="server5030.js" size="285" author="benety.goh@mongodb.com" created="Fri, 1 Nov 2013 20:36:05 +0000"/>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                <customfield id="customfield_10050" key="com.atlassian.jira.toolkit:comments">
                        <customfieldname># Replies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>24.0</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                <customfield id="customfield_12751" key="com.atlassian.jira.plugin.system.customfieldtypes:multiselect">
                        <customfieldname>Assigned Teams</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="25125"><![CDATA[Query Execution]]></customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                            <customfield id="customfield_13552" key="com.go2group.jira.plugin.crm:crm_generic_field">
                        <customfieldname>Case</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue><![CDATA[[500A000000UaYqdIAF]]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                            <customfield id="customfield_10055" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>Date of 1st Reply</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Thu, 13 Sep 2012 18:10:15 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10052" key="com.atlassian.jira.toolkit:dayslastcommented">
                        <customfieldname>Days since reply</customfieldname>
                        <customfieldvalues>
                                        10 years, 19 weeks, 1 day ago
    
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_18254" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Dependencies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue><![CDATA[]]></customfieldvalue>


                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10057" key="com.atlassian.jira.toolkit:lastusercommented">
                        <customfieldname>Last comment by Customer</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>true</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10056" key="com.atlassian.jira.toolkit:lastupdaterorcommenter">
                        <customfieldname>Last commenter</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>alexander.golin@mongodb.com</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_11151" key="com.atlassian.jira.toolkit:LastCommentDate">
                        <customfieldname>Last public comment date</customfieldname>
                        <customfieldvalues>
                            10 years, 19 weeks, 1 day ago
                        </customfieldvalues>
                    </customfield>
                                                                                                                        <customfield id="customfield_10000" key="com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons">
                        <customfieldname>Old_Backport</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10000"><![CDATA[No]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_10051" key="com.atlassian.jira.toolkit:participants">
                        <customfieldname>Participants</customfieldname>
                        <customfieldvalues>
                                        <customfieldvalue>backlog-query-execution</customfieldvalue>
            <customfieldvalue>calebjones</customfieldvalue>
            <customfieldvalue>daniel.sinclair@nupe.com</customfieldvalue>
            <customfieldvalue>eliot</customfieldvalue>
            <customfieldvalue>glenn</customfieldvalue>
            <customfieldvalue>jblackburn</customfieldvalue>
            <customfieldvalue>root</customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_14254" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Product Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hroct3:</customfieldvalue>

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

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>4075</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_23361" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Requested By</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_22870" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Triagers</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_14350" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>serverRank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|ht0qjj:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                    </customfields>
    </item>
</channel>
</rss>