-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: None
-
Query Optimization
-
Fully Compatible
-
ALL
-
v8.0, v7.0, v6.0, v5.0
-
-
QO 2024-08-05
-
200
-
None
-
3
-
None
-
None
-
None
-
None
-
None
-
None
SUMMARY
On MongoDB server versions 6.0.0-6.0.23, 7.0.0-7.0.20, and 8.0.0-8.0.9, it is possible for $elemMatch with predicates affected by collation to use an index with incompatible collation due to a plan cache bug. Impacted queries can return results which miss documents that should have been included. Write operations that rely on queries that incorrectly miss documents may not correctly update those documents. This includes updates, deletes, and $merge/$out aggregations with impacted query filters. A subset of affected operations may instead assert during query planning.
ISSUE DESCRIPTION AND IMPACT
The issue occurs when there are (at least) two $elemMatch queries with the same query shape using the same collation, where one $elemMatch is collation-insensitive (i.e., is not affected by collation, like a match on a numeric value) and one is collation-sensitive (i.e., is affected by collation, like a match on a string value). If there is an index on the same field with a different collation, the first query is eligible to use the index, but the second query should not be eligible.
For example, given an index on field “a” with no collation specified, the following query may use the index:
db.collection.find({"a": {$elemMatch: {$gte: 123, $lte: 125}}}) .collation({locale: 'en', strength: 1, numericOrdering: true})
The following query has the same query shape, but it should not use the index:
db.collection.find({"a": {$elemMatch: {$gte: "á", $lte: "é"}}}) .collation({locale: 'en', strength: 1, numericOrdering: true})
A problem occurs if the first query creates a plan cache entry using the index with a different collation. If the second query has the same plan cache key, then it may erroneously use the incompatible index. This may result in assertions during query planning or incorrect query results. The incorrect query results can manifest as missing documents in query results or missing writes – documents which should have been updated or deleted were not, or documents which should have been inserted via $out/$merge were not.
DIAGNOSIS AND AFFECTED VERSIONS
Users running queries as described above prior to MongoDB 6.0.24, 7.0.21, or 8.0.10 may have been affected.
To confirm if the issue currently impacts a particular query, users can run the query via the “explain” command and observe the “planCacheKey” field. Then, users should observe the plans currently in the plan cache, for example via $planCacheStats. If there is an entry in the plan cache for the query’s planCacheKey, and if that entry represents a plan that uses an index with a different collation to answer the collation-sensitive $elemMatch, then the query is impacted. Note: explain output alone is not enough to determine if a query is currently impacted, because explain commands bypass the plan cache.
REMEDIATION AND WORKAROUNDS
Customers are recommended to upgrade to v6.0.24+, v7.0.21+, or v8.0.10+. For MongoDB Atlas Customers, your Atlas clusters will be upgraded automatically to the version containing the fix.
A workaround exists without upgrading the cluster. Users can instead add a hint() to the affected query, which causes the correct index to be used. On v8.0, customers can use Query Settings to avoid having to change application code, however it is important to note that the query settings would apply to all queries with a matching query shape. That includes both the collation-sensitive query and the collation-insensitive query.
—-----------------------------------------------------
Original description
The plan cache key should distinguish between two queries with predicates which differ in index compatibility due to index collation. This does not happen when $elemMatch is present in the predicate.
- causes
-
SERVER-93162 $elemMatch may attempt to erroneously use an index for comparison with arrays
-
- Closed
-
- is related to
-
SERVER-97503 Audit and fill gaps in collation testing
-
- Investigating
-