[JAVA-3888] BsonDocument.equals should consider field order Created: 13/Nov/20 Updated: 30/Mar/22 |
|
| Status: | Backlog |
| Project: | Java Driver |
| Component/s: | BSON |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Major - P3 |
| Reporter: | Kai Orend | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
When comparing two BsonDocuments using the BsonDocuments.equals() method the order of the fields does not seem to be considered. Currently {a:1, b:1}.equals({b:1,a:1}) 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. |
| Comments |
| Comment by Ross Lawley [ 23/Nov/20 ] | |||||
|
An alternative proposal could be to add a BsonDocument.strict() method to configure strict checking mode and check the flag in the equals() method. That way recursive equality checks for sub documents etc can be handled easily and users could configure the setting globally via a custom BsonDocumentCodec. | |||||
| Comment by Jeffrey Yemin [ 23/Nov/20 ] | |||||
|
I think I see now why we did it this way: it'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:
So I'm convinced now that this is not a bug and should not be changed. We can consider adding an orderedEquals method to both classes to handle this particular use case. | |||||
| Comment by Jeffrey Yemin [ 19/Nov/20 ] | |||||
|
I tested both Document and BasicDBObject, and they both work the same as BsonDocument: they ignore key order. So we have been consistent. | |||||
| Comment by Jeffrey Yemin [ 16/Nov/20 ] | |||||
|
I think it'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. 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 "undefined" and may change in a future release. | |||||
| Comment by Peter Williamson [ 16/Nov/20 ] | |||||
|
My 2c's worth: There's certainly a use case for a method that doesn't take order into account but given that order can be important equals should consider order. Perhaps contentsEquals could perform the current functionality. | |||||
| Comment by Kai Orend [ 16/Nov/20 ] | |||||
|
Hi ross.lawley,
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:
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. Kai | |||||
| Comment by Ross Lawley [ 16/Nov/20 ] | |||||
|
Hi kai.orend, What are your reasons for wanting to test insertion order? Just to note the server considers such documents as equal:
From the documented comparison / sort order for bson objects is:
So even the server doesn't appear to follow the ordering of the fields from within the Bson document. Ross |