[SERVER-13963] Different Results from nested array query Created: 16/May/14 Updated: 08/Feb/23 Resolved: 20/May/14 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Querying |
| Affects Version/s: | 2.6.0, 2.6.1 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Neil Lunn | Assignee: | David Storch |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
|||||||||||||||||||||||
| Operating System: | ALL | |||||||||||||||||||||||
| Steps To Reproduce: | The following issue was raised on Stack Overflow in this question. The data has been set up like this:
The following query when issued in 2.4 versions returns the desired result:
and result:
The same query issued in 2.6 does not return any result. This is questionable as I believe the correct form of the query should be:
Which will return the desired result in both versions. So not sure if the selection is a bug that was present in earlier releases or whether there is something causing that statement to fail in 2.6 releases. As a side note the question itself refers to creating an index on the collection:
Which causes the query to fail in earlier versions. This I believe to be correct due to the nested array than cannot be used as in index value. The second form of the query will not directly select an index unless that has been hinted in some way. In 2.6 a hint to that index will produce an error and a sort simply ignores the index. In 2.4 the index will be shown as selected in the explain output, but there will be no bounds selected. |
|||||||||||||||||||||||
| Participants: | ||||||||||||||||||||||||
| Description |
|
Querying elements within a nested array structure works differently in 2.6 releases than it does in prior 2.4 releases |
| Comments |
| Comment by David Storch [ 20/May/14 ] | |||||||||||||||||||||||||||||
|
To be documented in | |||||||||||||||||||||||||||||
| Comment by David Storch [ 20/May/14 ] | |||||||||||||||||||||||||||||
|
Hi all, The observed behavior change is actually a bug in the 2.4.x versions fixed in 2.6.0. Here's a quick proof that 2.4 was wrong:
A query should always return the same logical result set regardless of the set of indices that are available. 2.4 breaks this invariant, returning different results depending on whether or not the query can be indexed. This begs the question, what should the result of this query be? Should it return the document or not? I would argue that the answer is "no, it should not return the document". Let's break down the query bit-by-bit. First consider the outer piece,
Translated from MongoDB query language to English, this roughly means "the field 'sents.bi' is an array which has an element that matches whatever conditions are inside the $elemMatch.". The document indeed has two arrays with the path 'sents.bi', these being
In order for the document to match, at least one of the arrays must match the part of the query inside the $elemMatch:
This will only match if one of the arrays has the element 'a'. The array elements are the nested arrays ['a','b'], ['b','c'], ['x','y'], and ['y','z'], and none of these nested arrays are equal to 'a'. The key point here is that MongoDB does not reach recursively into nested arrays either for matching documents or for generating index keys. As an example, see the following shell session run against a 2.4.10 server:
Furthermore, note that the index keys for this document when there is an index {a: 1} are not the integers 1, 2, 3, and 4. Rather, there are two index keys: the array [1,2] and the array [3,4]. I hope this helps to clear up the behavior as it stands in the 2.6.x series of production releases. I'm going to resolve this ticket, but will get the process rolling with our documentation team in order to ensure that this appears clearly in the docs. Feel free to reach out with any further questions. Best, | |||||||||||||||||||||||||||||
| Comment by 耀星 张 [ 16/May/14 ] | |||||||||||||||||||||||||||||
|
The hint doesn't give me any error. And it gives me the following execution plan:
however, it still scanned the other object in the collection that doesn't event have a "sents" property. Is it expected behavior? |