|
$text queries against a compound text index pass an incorrect predicate to the index, unless the index isn't multikey (i.e. all documents have at most one indexable term).
Reproduce with the following:
function runTest(textData) {
|
db.foo.drop();
|
db.foo.insert({a: 17, b: "irrelevant"});
|
db.foo.insert({a: 17, b: textData});
|
db.foo.ensureIndex({a: 1, b: "text"});
|
return db.foo.count({a: 17, $text: {$search: "foo"}});
|
}
|
|
print(runTest("foo")); // correct: outputs 1 (text index is not multikey)
|
print(runTest("foo bar")); // incorrect: outputs 2 (text index is multikey)
|
Output for the "correct" case:
2014-01-13T19:56:12.455-0500 [conn3] enumerator received root:
|
$and
|
a $gt 0.0 First: 0 notFirst: full path: a
|
TEXT : query=hello, language = , tag=First: notFirst: 0 full path: _fts
|
|
2014-01-13T19:56:12.455-0500 [conn3] Tagging memoID 0
|
2014-01-13T19:56:12.455-0500 [conn3] Enumerator: memo right before moving:
|
2014-01-13T19:56:12.455-0500 [conn3] [Node #0]: AND enumstate counter 0
|
choice 0:
|
subnodes:
|
idx[0]
|
pos 0 pred a $gt 0.0
|
|
pos 1 pred TEXT : query=hello, language = , tag=NULL
|
Output for the "incorrect" case:
2014-01-13T19:55:46.798-0500 [conn2] enumerator received root:
|
$and
|
a $gt 0.0 First: 0 notFirst: full path: a
|
TEXT : query=hello, language = , tag=First: notFirst: 0 full path: _fts
|
|
2014-01-13T19:55:46.798-0500 [conn2] Tagging memoID 0
|
2014-01-13T19:55:46.798-0500 [conn2] Enumerator: memo right before moving:
|
2014-01-13T19:55:46.798-0500 [conn2] [Node #0]: AND enumstate counter 0
|
choice 0:
|
subnodes:
|
idx[0]
|
pos 0 pred a $gt 0.0
|
Original description below.
So, given a collection inventory :
{ _id: 1, dept: "tech", description: "a fun green computer" }
|
{ _id: 2, dept: "tech", description: "a wireless red mouse" }
|
{ _id: 3, dept: "kitchen", description: "a green placemat" }
|
{ _id: 4, dept: "kitchen", description: "a red peeler" }
|
{ _id: 5, dept: "food", description: "a green apple" }
|
{ _id: 6, dept: "food", description: "a red potato" }
|
and the following compound index:
db.inventory.ensureIndex( { dept: 1, description: "text" } )
|
The following query seems to be 'or'ing the conditions or something
> db.inventory.find( { dept: {$in:[ "kitchen", "food" ] }, $text: { $search: "green" } } )
|
{ "_id" : 5, "dept" : "food", "description" : "a green apple" }
|
{ "_id" : 6, "dept" : "food", "description" : "a red potato" } // This shouldn't return
|
{ "_id" : 3, "dept" : "kitchen", "description" : "a green placemat" }
|
{ "_id" : 4, "dept" : "kitchen", "description" : "a red peeler" } // this shouldn't return either
|
|