[SERVER-43285] Improve error message when certain operators are used in change streams Created: 11/Sep/19  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Daniel Aprahamian (Inactive) Assignee: Backlog - Query Optimization
Resolution: Unresolved Votes: 1
Labels: neweng, qopt-team
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
is depended on by NODE-2162 MongoError: "$match with $text is onl... Closed
Assigned Teams:
Query Optimization
Participants:

 Description   

Spawned b/c of NODE-2162

The code below produces the error "$match with $text is only allowed as the first pipeline stage", even though $match with $text is the only pipeline stage. Is there a subtle syntax error somewhere, or what else might be going on?

const collectionChangeStream = collection.watch([
  { $match: { $text: { $search: 'cake' } } },
]);
 
collectionChangeStream.on('change', next => {
  console.log(next);
});

The code above results in sending a pipeline to the server that looks something like this:

[
  { $changeStream: { fullDocument: 'default' } },
  { $match: { $text: { $search: 'cake' } } }
]

This is a result of an implementation detail of change streams. The error message "$match with $text is only allowed as the first pipeline stage" does not clearly identify to a user what exactly went wrong, and how they can fix it.

Is it possible to have a more informative error message in this case?



 Comments   
Comment by David Percy [ 29/Jan/21 ]

The same thing happens with views:

db.c.insert({msg: 'hi'})
db.c.createIndex({'$**': 'text'})
db.createView('v', 'c', [{$facet:{docs:[]}}])
db.v.aggregate({$match:{$text:{$search:'hi'}}})

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$match with $text is only allowed as the first pipeline stage",
	"code" : 17313,
	"codeName" : "Location17313"
} with original command request: {
	"aggregate" : "v",
	"pipeline" : [
		{
			"$match" : {
				"$text" : {
					"$search" : "hi"
				}
			}
		}
	],
	"cursor" : {
 
	},
	"lsid" : {
		"id" : UUID("c6d0fccb-b99f-4f37-ab6e-1295ab9ea856")
	}
}

Although you get a different message when you use .find():

db.v.find({$text:{$search:'hi'}})

Error: error: {
	"ok" : 0,
	"errmsg" : "text index required for $text query (no such collection 'test.v')",
	"code" : 27,
	"codeName" : "IndexNotFound"
}

Generated at Thu Feb 08 05:02:46 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.