0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

BUG SERVER-29 matcher access objects in arrays correctly

This commit is contained in:
Aaron 2009-04-22 14:11:53 -04:00
parent cb9e6153dd
commit b9617339d4
3 changed files with 40 additions and 21 deletions

View File

@ -405,6 +405,7 @@ namespace mongo {
int ret = matchesNe( fieldName, *i, obj, deep );
if ( ret != 1 )
return ret;
// code to handle 0 (missing) return value doesn't deal with nin yet
}
return 1;
}
@ -414,18 +415,36 @@ namespace mongo {
e = obj.getFieldUsingIndexNames(fieldName, constrainIndexKey_);
assert( !e.eoo() );
} else {
if ( isArr ) {
BSONObjIterator ai(obj);
bool found = false;
while ( ai.more() ) {
BSONElement z = ai.next();
if ( z.type() == Object ) {
BSONObj eo = z.embeddedObject();
int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep);
if ( cmp > 0 ) {
if ( deep ) *deep = true;
return 1;
} else if ( cmp < 0 ) {
found = true;
}
}
}
return found ? -1 : 0;
}
const char *p = strchr(fieldName, '.');
if ( p ) {
string left(fieldName, p-fieldName);
BSONElement e = obj.getField(left.c_str());
if ( e.eoo() )
BSONElement se = obj.getField(left.c_str());
if ( se.eoo() )
return 0;
if ( e.type() != Object && e.type() != Array )
if ( se.type() != Object && se.type() != Array )
return -1;
BSONObj eo = e.embeddedObject();
return matchesDotted(p+1, toMatch, eo, compareOp, deep, e.type() == Array);
BSONObj eo = se.embeddedObject();
return matchesDotted(p+1, toMatch, eo, compareOp, deep, se.type() == Array);
} else {
e = obj.getField(fieldName);
}
@ -444,22 +463,8 @@ namespace mongo {
}
}
}
else if ( isArr ) {
BSONObjIterator ai(obj);
while ( ai.more() ) {
BSONElement z = ai.next();
if ( z.type() == Object ) {
BSONObj eo = z.embeddedObject();
int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep);
if ( cmp > 0 ) {
if ( deep ) *deep = true;
return 1;
}
}
}
}
else if ( e.eoo() ) {
// 0 indicatse "missing element"
// 0 indicates "missing element"
return 0;
}
return -1;

View File

@ -449,6 +449,19 @@ namespace QueryTests {
}
};
class SubobjectInArray : public ClientBase {
public:
~SubobjectInArray() {
client().dropCollection( "querytests.SubobjectInArray" );
}
void run() {
const char *ns = "querytests.SubobjectInArray";
client().insert( ns, fromjson( "{a:[{b:{c:1}}]}" ) );
ASSERT( !client().findOne( ns, BSON( "a.b.c" << 1 ) ).isEmpty() );
ASSERT( !client().findOne( ns, fromjson( "{'a.c':null}" ) ).isEmpty() );
}
};
class All : public UnitTest::Suite {
public:
All() {
@ -473,6 +486,7 @@ namespace QueryTests {
add< AutoResetIndexCache >();
add< UniqueIndex >();
add< UniqueIndexPreexistingData >();
add< SubobjectInArray >();
}
};

View File

@ -26,7 +26,7 @@ doTest = function() {
assert.eq( 4, t.find( { a: { $nin: [ 2 ] } } ).count() );
t.save( { a: [ { b: [ 10, 11 ] }, 11 ] } );
assert.eq( 7, t.find( { 'a.b': { $nin: [ 10 ] } } ).count() );
assert.eq( 0, t.find( { 'a.b': { $nin: [ 10 ] } } ).count() );
assert.eq( 7, t.find( { a: { $nin: [ 11 ] } } ).count() );
t.save( { a: { b: [ 20, 30 ] } } );