-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: 2.6.0, 2.6.1
-
Component/s: Index Maintenance, Querying
-
None
-
ALL
-
ISSUE SUMMARY
Queries with multiple negations over the same field joined by an $or fail when an index is present on that field, because wrong index bounds are being computed. For example:
db.t.ensureIndex({a: 1}) db.t.find({$or: [{a: {$ne: 3}}, {a: {$ne: 4}}]})
The above query is always true and should return all documents, but does not.
USER IMPACT
Queries of this type fail with an assertion error.
WORKAROUNDS
Whenever possible, rewrite these queries to avoid having multiple negations over the same field.
AFFECTED VERSIONS
Production releases 2.6.0 and 2.6.1 are affected by this issue.
FIX VERSION
The fix is included in the 2.6.2 production release.
RESOLUTION DETAILS
The problem occurs because the wrong index bounds are computed in the presence of multiple negations on the same field joined by an $or. Version 2.6.2 constructs the correct index bounds.
Original description
I know the condition itself does not make much sense. But there is a bug nevertheless.
To recreate:
$ wget http://hci.stanford.edu/jheer/workshop/data/worldbank/worldbank.csv $ mongoimport -d test --file worldbank.csv --type csv --headerline $ mongo test MongoDB shell version: 2.6.0 connecting to: test > db.worldbank.findOne() { "_id" : ObjectId("536cb371267a41551a350ce0"), "Country" : "Belarus", "Year" : 2000, "CO2 emissions (metric tons per capita)" : 5.91, "Electric power consumption (kWh per capita)" : 2988.71, "Energy use (kg of oil equivalent per capita)" : 2459.67, "Fertility rate, total (births per woman)" : 1.29, "GNI per capita, Atlas method (current US$)" : "1.38E+03", "Internet users (per 1,000 people)" : 18.69, "Life expectancy at birth, total (years)" : 68.01, "Military expenditure (% of GDP)" : 1.26, "Population, total" : "1.00E+07", "Prevalence of HIV, total (% of population ages 15-49)" : "" } > db.worldbank.find({$or: [{"CO2 emissions (metric tons per capita)": {$ne:6}}, {"CO2 emissions (metric tons per capita)":{$ne:5}}]}).count() 1362 > db.worldbank.createIndex({"CO2 emissions (metric tons per capita)":1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.worldbank.find({$or: [{"CO2 emissions (metric tons per capita)": {$ne:6}}, {"CO2 emissions (metric tons per capita)":{$ne:5}}]}).count() 2014-05-09T16:24:45.777+0530 count failed: { "code" : 0, "ok" : 0, "errmsg" : "0 assertion src/mongo/db/query/index_bounds_builder.cpp:843" } at src/mongo/shell/query.js:191
Another similar error that occurred for the same reasons: This happened in pymongo.
OperationFailure: command SON([('count', u'DS_1'), ('fields', {u'batch_id': 0, u'_id': 0, u'sequence_number': 0}), ('query', {u'$and': [{u'$and': [{u'$or': [{u'column_5': {u'$options': u'-i', u'$regex': u'^(?!catefory_sale$)'}}, {u'column_5': {u'$options': u'-i', u'$regex': u'^(?!category_disCount$)'}}]}, {u'$or': [{u'column_9': {u'$ne': 0}}, {u'column_9': {u'$ne': 1}}]}]}, {}]})]) failed: exception: assertion src/mongo/db/query/plan_enumerator.cpp:1011