mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 00:56:44 +01:00
Some basic array index improvements
This commit is contained in:
parent
7bb4001e9a
commit
b3d2c2ebd8
@ -415,7 +415,7 @@ void IndexDetails::kill() {
|
||||
Keys will be left empty if key not found in the object.
|
||||
*/
|
||||
void IndexDetails::getKeysFromObject( const BSONObj& obj, set<BSONObj>& keys) const {
|
||||
BSONObj keyPattern = info.obj().getObjectField("key"); // e.g., keyPattern == { ts : 1 }
|
||||
BSONObj keyPattern = info.obj().getObjectField("key"); // e.g., keyPattern == { ts : 1 }
|
||||
if( keyPattern.objsize() == 0 ) {
|
||||
cout << keyPattern.toString() << endl;
|
||||
cout << info.obj().toString() << endl;
|
||||
@ -425,22 +425,43 @@ void IndexDetails::getKeysFromObject( const BSONObj& obj, set<BSONObj>& keys) co
|
||||
BSONObj key = obj.extractFieldsDotted(keyPattern, b);
|
||||
if( key.isEmpty() )
|
||||
return;
|
||||
BSONElement f = key.firstElement();
|
||||
if( f.type() != Array ) {
|
||||
BSONObjIterator keyIter( key );
|
||||
BSONElement arrayElt;
|
||||
int arrayPos = -1;
|
||||
for( int i = 0; keyIter.more(); ++i ) {
|
||||
BSONElement e = keyIter.next();
|
||||
if( e.eoo() ) break;
|
||||
if( e.type() == Array ) {
|
||||
uassert( "Index cannot be created on parallel arrays.",
|
||||
arrayPos == -1 );
|
||||
arrayPos = i;
|
||||
arrayElt = e;
|
||||
}
|
||||
}
|
||||
if( arrayPos == -1 ) {
|
||||
b.decouple();
|
||||
key.iWillFree();
|
||||
assert( !key.isEmpty() );
|
||||
keys.insert(key);
|
||||
return;
|
||||
}
|
||||
BSONObj arr = f.embeddedObject();
|
||||
BSONObjIterator i(arr);
|
||||
while( i.more() ) {
|
||||
BSONElement e = i.next();
|
||||
BSONObj arr = arrayElt.embeddedObject();
|
||||
BSONObjIterator arrIter(arr);
|
||||
while( arrIter.more() ) {
|
||||
BSONElement e = arrIter.next();
|
||||
if( e.eoo() ) break;
|
||||
BSONObjBuilder b;
|
||||
|
||||
b.appendAs(e, f.fieldName());
|
||||
BSONObjBuilder b;
|
||||
BSONObjIterator keyIter( key );
|
||||
for( int i = 0; keyIter.more(); ++i ) {
|
||||
BSONElement f = keyIter.next();
|
||||
if ( f.eoo() ) break;
|
||||
if ( i != arrayPos )
|
||||
b.append( f );
|
||||
else
|
||||
b.appendAs( e, arrayElt.fieldName() );
|
||||
}
|
||||
|
||||
BSONObj o = b.doneAndDecouple();
|
||||
assert( !o.isEmpty() );
|
||||
keys.insert(o);
|
||||
|
@ -32,6 +32,15 @@ namespace NamespaceTests {
|
||||
Base() {
|
||||
dblock lk;
|
||||
setClient( ns() );
|
||||
}
|
||||
~Base() {
|
||||
if( id_.info.isNull() )
|
||||
return;
|
||||
theDataFileMgr.deleteRecord( ns(), id_.info.rec(), id_.info );
|
||||
ASSERT( theDataFileMgr.findAll( ns() )->eof() );
|
||||
}
|
||||
protected:
|
||||
void create() {
|
||||
BSONObjBuilder builder;
|
||||
builder.append( "ns", ns() );
|
||||
builder.append( "name", "testIndex" );
|
||||
@ -39,14 +48,8 @@ namespace NamespaceTests {
|
||||
BSONObj bobj = builder.done();
|
||||
id_.info = theDataFileMgr.insert( ns(), bobj.objdata(), bobj.objsize() );
|
||||
// head not needed for current tests
|
||||
// idx_.head = BtreeBucket::addHead( id_ );
|
||||
// idx_.head = BtreeBucket::addHead( id_ );
|
||||
}
|
||||
~Base() {
|
||||
// FIXME cleanup all btree buckets.
|
||||
theDataFileMgr.deleteRecord( ns(), id_.info.rec(), id_.info );
|
||||
ASSERT( theDataFileMgr.findAll( ns() )->eof() );
|
||||
}
|
||||
protected:
|
||||
static const char* ns() { return "sys.unittest.indexdetailstests"; }
|
||||
const IndexDetails& id() { return id_; }
|
||||
virtual BSONObj key() const {
|
||||
@ -55,11 +58,22 @@ namespace NamespaceTests {
|
||||
return k.doneAndDecouple();
|
||||
}
|
||||
BSONObj aDotB() const {
|
||||
BSONObjBuilder a;
|
||||
BSONObjBuilder b;
|
||||
b.append( "b", 1 );
|
||||
a.append( "a", b.done() );
|
||||
return a.doneAndDecouple();
|
||||
BSONObjBuilder k;
|
||||
k.append( "a.b", 1 );
|
||||
return k.doneAndDecouple();
|
||||
}
|
||||
BSONObj aAndB() const {
|
||||
BSONObjBuilder k;
|
||||
k.append( "a", 1 );
|
||||
k.append( "b", 1 );
|
||||
return k.doneAndDecouple();
|
||||
}
|
||||
static vector< int > shortArray() {
|
||||
vector< int > a;
|
||||
a.push_back( 1 );
|
||||
a.push_back( 2 );
|
||||
a.push_back( 3 );
|
||||
return a;
|
||||
}
|
||||
private:
|
||||
IndexDetails id_;
|
||||
@ -68,6 +82,7 @@ namespace NamespaceTests {
|
||||
class Create : public Base {
|
||||
public:
|
||||
void run() {
|
||||
create();
|
||||
ASSERT_EQUALS( "testIndex", id().indexName() );
|
||||
ASSERT_EQUALS( ns(), id().parentNS() );
|
||||
// check equal
|
||||
@ -78,6 +93,7 @@ namespace NamespaceTests {
|
||||
class GetKeysFromObjectSimple : public Base {
|
||||
public:
|
||||
void run() {
|
||||
create();
|
||||
BSONObjBuilder b, e;
|
||||
b.append( "b", 4 );
|
||||
b.append( "a", 5 );
|
||||
@ -92,6 +108,7 @@ namespace NamespaceTests {
|
||||
class GetKeysFromObjectDotted : public Base {
|
||||
public:
|
||||
void run() {
|
||||
create();
|
||||
BSONObjBuilder a, e, b;
|
||||
b.append( "b", 4 );
|
||||
a.append( "a", b.done() );
|
||||
@ -102,9 +119,9 @@ namespace NamespaceTests {
|
||||
ASSERT_EQUALS( 1, keys.size() );
|
||||
// FIXME Why doesn't woCompare expand sub elements?
|
||||
// ASSERT( !keys.begin()->woCompare( e.done() ) );
|
||||
ASSERT_EQUALS( string( "a" ), keys.begin()->firstElement().fieldName() );
|
||||
ASSERT_EQUALS( string( "b" ), keys.begin()->firstElement().embeddedObject().firstElement().fieldName() );
|
||||
ASSERT_EQUALS( 4, keys.begin()->firstElement().embeddedObject().firstElement().number() );
|
||||
cout << "first key: " << keys.begin()->toString() << endl;
|
||||
ASSERT_EQUALS( string( "b" ), keys.begin()->firstElement().fieldName() );
|
||||
ASSERT_EQUALS( 4, keys.begin()->firstElement().number() );
|
||||
}
|
||||
private:
|
||||
virtual BSONObj key() const { return aDotB(); }
|
||||
@ -113,12 +130,9 @@ namespace NamespaceTests {
|
||||
class GetKeysFromArraySimple : public Base {
|
||||
public:
|
||||
void run() {
|
||||
vector< int > a;
|
||||
a.push_back( 1 );
|
||||
a.push_back( 2 );
|
||||
a.push_back( 3 );
|
||||
create();
|
||||
BSONObjBuilder b;
|
||||
b.append( "a", a );
|
||||
b.append( "a", shortArray()) ;
|
||||
|
||||
set< BSONObj > keys;
|
||||
id().getKeysFromObject( b.done(), keys );
|
||||
@ -131,33 +145,99 @@ namespace NamespaceTests {
|
||||
}
|
||||
};
|
||||
|
||||
class GetKeysFromSecondLevelArray : public Base {
|
||||
class GetKeysFromArrayFirstElement : public Base {
|
||||
public:
|
||||
void run() {
|
||||
vector< int > a;
|
||||
a.push_back( 1 );
|
||||
a.push_back( 2 );
|
||||
a.push_back( 3 );
|
||||
create();
|
||||
BSONObjBuilder b;
|
||||
b.append( "b", a );
|
||||
BSONObjBuilder c;
|
||||
c.append( "a", b.done() );
|
||||
b.append( "a", shortArray() );
|
||||
b.append( "b", 2 );
|
||||
|
||||
set< BSONObj > keys;
|
||||
id().getKeysFromObject( c.done(), keys );
|
||||
id().getKeysFromObject( b.done(), keys );
|
||||
ASSERT_EQUALS( 3, keys.size() );
|
||||
int j = 1;
|
||||
for( set< BSONObj >::iterator i = keys.begin(); i != keys.end(); ++i, ++j ) {
|
||||
ASSERT_EQUALS( string( "a" ), i->firstElement().fieldName() );
|
||||
ASSERT_EQUALS( string( "a" ), i->firstElement().embeddedObject().firstElement().fieldName() );
|
||||
ASSERT_EQUALS( j, i->firstElement().embeddedObject().firstElement().number() );
|
||||
ASSERT_EQUALS( j, i->firstElement().number() );
|
||||
ASSERT_EQUALS( 2, i->getField( "b" ).number() );
|
||||
}
|
||||
}
|
||||
private:
|
||||
virtual BSONObj key() const { return aAndB(); }
|
||||
};
|
||||
|
||||
class GetKeysFromArraySecondElement : public Base {
|
||||
public:
|
||||
void run() {
|
||||
create();
|
||||
BSONObjBuilder b;
|
||||
b.append( "first", 5 );
|
||||
b.append( "a", shortArray()) ;
|
||||
|
||||
set< BSONObj > keys;
|
||||
id().getKeysFromObject( b.done(), keys );
|
||||
ASSERT_EQUALS( 3, keys.size() );
|
||||
int j = 1;
|
||||
for( set< BSONObj >::iterator i = keys.begin(); i != keys.end(); ++i, ++j ) {
|
||||
ASSERT_EQUALS( string( "first" ), i->firstElement().fieldName() );
|
||||
ASSERT_EQUALS( j, i->getField( "a" ).number() );
|
||||
}
|
||||
}
|
||||
private:
|
||||
virtual BSONObj key() const {
|
||||
BSONObjBuilder k;
|
||||
k.append( "first", 1 );
|
||||
k.append( "a", 1 );
|
||||
return k.doneAndDecouple();
|
||||
}
|
||||
};
|
||||
|
||||
class GetKeysFromSecondLevelArray : public Base {
|
||||
public:
|
||||
void run() {
|
||||
create();
|
||||
BSONObjBuilder b;
|
||||
b.append( "b", shortArray() );
|
||||
BSONObjBuilder a;
|
||||
a.append( "a", b.done() );
|
||||
|
||||
set< BSONObj > keys;
|
||||
id().getKeysFromObject( a.done(), keys );
|
||||
cout << "key: " << keys.begin()->toString() << endl;
|
||||
ASSERT_EQUALS( 3, keys.size() );
|
||||
int j = 1;
|
||||
for( set< BSONObj >::iterator i = keys.begin(); i != keys.end(); ++i, ++j ) {
|
||||
ASSERT_EQUALS( string( "b" ), i->firstElement().fieldName() );
|
||||
ASSERT_EQUALS( j, i->firstElement().number() );
|
||||
}
|
||||
}
|
||||
private:
|
||||
virtual BSONObj key() const { return aDotB(); }
|
||||
};
|
||||
|
||||
class ParallelArraysBasic : public Base {
|
||||
public:
|
||||
void run() {
|
||||
create();
|
||||
BSONObjBuilder b;
|
||||
b.append( "a", shortArray() );
|
||||
b.append( "b", shortArray() );
|
||||
|
||||
set< BSONObj > keys;
|
||||
ASSERT_EXCEPTION( id().getKeysFromObject( b.done(), keys ),
|
||||
UserAssertionException );
|
||||
}
|
||||
private:
|
||||
virtual BSONObj key() const { return aAndB(); }
|
||||
};
|
||||
} // namespace IndexDetailsTests
|
||||
|
||||
// TODO
|
||||
// array subelement
|
||||
// parallel arrays complex
|
||||
// allowed multi array indexes
|
||||
|
||||
class All : public UnitTest::Suite {
|
||||
public:
|
||||
All() {
|
||||
@ -165,8 +245,10 @@ namespace NamespaceTests {
|
||||
add< IndexDetailsTests::GetKeysFromObjectSimple >();
|
||||
add< IndexDetailsTests::GetKeysFromObjectDotted >();
|
||||
add< IndexDetailsTests::GetKeysFromArraySimple >();
|
||||
// Not working yet
|
||||
//add< IndexDetailsTests::GetKeysFromSecondLevelArray >();
|
||||
add< IndexDetailsTests::GetKeysFromArrayFirstElement >();
|
||||
add< IndexDetailsTests::GetKeysFromArraySecondElement >();
|
||||
add< IndexDetailsTests::GetKeysFromSecondLevelArray >();
|
||||
add< IndexDetailsTests::ParallelArraysBasic >();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user