[SERVER-13039] AND of (indexed expression) with (OR containing TEXT) returns incorrect results Created: 04/Mar/14  Updated: 11/Jul/16  Resolved: 10/Mar/14

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 2.6.0-rc0
Fix Version/s: 2.6.0-rc2

Type: Bug Priority: Major - P3
Reporter: Siyuan Zhou Assignee: David Storch
Resolution: Done Votes: 0
Labels: 26qa
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File fts_complex_plan.js    
Issue Links:
Depends
Operating System: ALL
Participants:

 Description   

> db.test.ensureIndex({num:1})
WriteResult({ "nInserted" : 1 })
> db.test.ensureIndex({words:"text"})
WriteResult({ "nInserted" : 1 })
> db.test.insert({_id:1, num: 0})
WriteResult({ "nInserted" : 1 })
> db.test.insert({_id:2, num: 0, words:"foo"})
WriteResult({ "nInserted" : 1 })
> db.test.find({num:0, $or:[{_id:2}, {$text:{$search:"foo"}}]})
{ "_id" : 1, "num" : 0 } // wrong! this doc doesn't match either clause of the $or.
{ "_id" : 2, "num" : 0, "words" : "foo" }
> db.test.find({num:0, $or:[{_id:2}, {$text:{$search:"foo"}}]}).explain(true)
{
	"cursor" : "BtreeCursor num_1", // invalid plan! queries with TEXT must choose text index plan.
	"isMultiKey" : false,
	"n" : 2,
	"nscannedObjects" : 2,
	"nscanned" : 2,
	"nscannedObjectsAllPlans" : 4,
	"nscannedAllPlans" : 6,
	"scanAndOrder" : false,
	"indexOnly" : false,
	"nYields" : 0,
	"nChunkSkips" : 0,
	"millis" : 2,
	"indexBounds" : {
		"num" : [
			[
				0,
				0
			]
		]
	},
	"allPlans" : [
		{
			"cursor" : "BtreeCursor num_1",
			"isMultiKey" : false,
			"n" : 2,
			"nscannedObjects" : 2,
			"nscanned" : 2,
			"scanAndOrder" : false,
			"indexOnly" : false,
			"nChunkSkips" : 0,
			"indexBounds" : {
				"num" : [
					[
						0,
						0
					]
				]
			}
		},
		{
			"clauses" : [
				{
					"cursor" : "TextCursor",
					"n" : 0,
					"nscannedObjects" : 1,
					"nscanned" : 1,
					"scanAndOrder" : false,
					"nChunkSkips" : 0
				},
				{
					"cursor" : "BtreeCursor _id_",
					"isMultiKey" : false,
					"n" : 0,
					"nscannedObjects" : 0,
					"nscanned" : 0,
					"scanAndOrder" : false,
					"indexOnly" : true,
					"nChunkSkips" : 0,
					"indexBounds" : {
						"_id" : [
							[
								2,
								2
							]
						]
					}
				}
			],
			"cursor" : "QueryOptimizerCursor", // the correct plan!
			"n" : 0,
			"nscannedObjects" : 1,
			"nscanned" : 1,
			"scanAndOrder" : false,
			"nChunkSkips" : 0
		},
		{
			"cursor" : "Complex Plan",
			"n" : 0,
			"nscannedObjects" : 1,
			"nscanned" : 3,
			"nChunkSkips" : 0
		}
	],
	"server" : "Rassi-MacBook-Pro.local:27017",
	"filterSet" : false,
	"stats" : {
		"type" : "KEEP_MUTATIONS",
		"works" : 4,
		"yields" : 0,
		"unyields" : 0,
		"invalidates" : 0,
		"advanced" : 2,
		"needTime" : 0,
		"needFetch" : 0,
		"isEOF" : 1,
		"children" : [
			{
				"type" : "FETCH",
				"works" : 3,
				"yields" : 0,
				"unyields" : 0,
				"invalidates" : 0,
				"advanced" : 2,
				"needTime" : 0,
				"needFetch" : 0,
				"isEOF" : 1,
				"alreadyHasObj" : 0,
				"forcedFetches" : 0,
				"matchTested" : 2,
				"children" : [
					{
						"type" : "IXSCAN",
						"works" : 2,
						"yields" : 0,
						"unyields" : 0,
						"invalidates" : 0,
						"advanced" : 2,
						"needTime" : 0,
						"needFetch" : 0,
						"isEOF" : 1,
						"keyPattern" : "{ num: 1.0 }",
						"boundsVerbose" : "field #0['num']: [0.0, 0.0]",
						"isMultiKey" : 0,
						"yieldMovedCursor" : 0,
						"dupsTested" : 0,
						"dupsDropped" : 0,
						"seenInvalidated" : 0,
						"matchTested" : 0,
						"keysExamined" : 2,
						"children" : [ ]
					}
				]
			}
		]
	}
}

Original description:

With the following query, the last assertion failed.

assert: [[ 1, 2, 3, 4, 5, 6 ]] != [[ 2, 3, 4, 5 ]] are not equal : undefined

function expectedIds(cursor, expectedIds) {
  var results = cursor.toArray()
  var ids = results.map(function(result){ return result._id; });
  assert.eq(ids.sort(), expectedIds);
}
 
db.test.drop()
db.test.insert({ _id: 1, words: "dog", num: 3 })
db.test.insert({ _id: 2, words: "dog cat", num: 3})
db.test.insert({ _id: 3, words: "dog cat cat", num: 1, loc: [ 20, 20 ] })
db.test.insert({ _id: 4, words: "dog cat cat", num: 2, loc: [ 40, 40 ] })
db.test.insert({ _id: 5, words: "cat", num: 4, array: [ { a: 1, b: 2 }, { a: 1, b: 0 } ] })
db.test.insert({ _id: 6, words: "gato", num: 5, language: "spanish" })
 
db.test.dropIndexes();
db.test.ensureIndex({ words: "text" });
db.test.ensureIndex({ num: 1 });
var query_or1 = { $or: [ { $text: { $search: "cat"} }, { num: 2 }] }; // [2, 3, 4, 5]
var query_or2 = { $or: [ { _id: { $gt: 4 } }, { num: { $lt: 4 } } ]}; // [1, 2, 3, 4, 5, 6]
var query_and = { $and: [ query_or1, query_or2 ]};
expectedIds(db.test.find(query_or1), [2, 3, 4, 5]);
expectedIds(db.test.find(query_or2), [1, 2, 3, 4, 5, 6]);
expectedIds(db.test.find(query_and), [2, 3, 4, 5]);



 Comments   
Comment by Githook User [ 10/Mar/14 ]

Author:

{u'username': u'dstorch', u'name': u'David Storch', u'email': u'david.storch@10gen.com'}

Message: SERVER-13039 handle subnodes which require an index during plan enumeration
Branch: master
https://github.com/mongodb/mongo/commit/25596dbf48b18a76d3d2cdfdf1fcf23a43e46316

Generated at Thu Feb 08 03:30:26 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.