Skip to content

Commit

Permalink
geo indexing with nested multikeys now works as non-nested
Browse files Browse the repository at this point in the history
  • Loading branch information
Greg Studer committed Jan 28, 2011
1 parent aef67c5 commit 2cf0b20
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
40 changes: 34 additions & 6 deletions db/geo/2d.cpp
Expand Up @@ -164,12 +164,37 @@ namespace mongo {

_hash( embed ).append( b , "" );

for ( size_t i=0; i<_other.size(); i++ ) {
BSONElement e = obj.getFieldDotted(_other[i]);
if ( e.eoo() )
e = _spec->missingField();
b.appendAs( e , "" );
}
// Go through all the other index keys
for ( vector<string>::const_iterator i = _other.begin(); i != _other.end(); ++i ){

// Get *all* fields for the index key
BSONElementSet eSet;
obj.getFieldsDotted( *i, eSet );


if ( eSet.size() == 0 )
b.appendAs( _spec->missingField(), "" );
else if ( eSet.size() == 1 )
b.appendAs( *(eSet.begin()), "" );
else{

// If we have more than one key, store as an array of the objects
// TODO: Store multiple keys?

BSONArrayBuilder aBuilder;

for( BSONElementSet::iterator ei = eSet.begin(); ei != eSet.end(); ++ei ){
aBuilder.append( *ei );
}

BSONArray arr = aBuilder.arr();

b.append( "", arr );

}

}

keys.insert( b.obj() );
}

Expand Down Expand Up @@ -276,6 +301,9 @@ namespace mongo {
}
}
case Array:
// Non-geo index data is stored in a non-standard way, cannot use for exact lookups with
// additional criteria
if ( query.nFields() > 1 ) return USELESS;
return HELPFUL;
default:
return USELESS;
Expand Down
4 changes: 2 additions & 2 deletions jstests/geo_circle2.js
Expand Up @@ -22,5 +22,5 @@ t.insert({ "uid" : 355844 , "loc" : { "x" : 34 , "y" : -4} ,"categories" : [ "sp
assert.eq( 10 , t.find({ "loc" : { "$within" : { "$center" : [ { "x" : 0 ,"y" : 0} , 50]}} } ).itcount() , "A" );
assert.eq( 6 , t.find({ "loc" : { "$within" : { "$center" : [ { "x" : 0 ,"y" : 0} , 50]}}, "categories" : "sports" } ).itcount() , "B" );

// FIXME: FAILS : When not a $near or $within query, geo code not activated, and so geoindex with array keys misinterpreted
//assert.eq( 1 , t.find({ "loc" : { "x" : -36, "y" : -8}, "categories" : "sports" }).itcount(), "C" )
// When not a $near or $within query, geo index should not be used. Fails if geo index is used.
assert.eq( 1 , t.find({ "loc" : { "x" : -36, "y" : -8}, "categories" : "sports" }).itcount(), "C" )
21 changes: 19 additions & 2 deletions jstests/geo_circle2a.js
Expand Up @@ -4,5 +4,22 @@ db.test.drop()
db.test.insert({ p : [1112,3473], t : [{ k : 'a', v : 'b' }, { k : 'c', v : 'd' }] })
db.test.ensureIndex({ p : '2d', 't.k' : 1 }, { min : 0, max : 10000 })

// FIXME: FAILS, since multikeys nested as sub-objects are not returned by getKeys() for 2d indexing
//assert(1 == db.test.find({p:[1112,3473],'t.k':'a'}).count()), "A")
// Succeeds, since on direct lookup should not use the index
assert(1 == db.test.find({p:[1112,3473],'t.k':'a'}).count(), "A")
// Succeeds and uses the geo index
assert(1 == db.test.find({p:{$within:{$box:[[1111,3472],[1113,3475]]}}, 't.k' : 'a' }).count(), "B")


db.test.drop()
db.test.insert({ point:[ 1, 10 ], tags : [ { k : 'key', v : 'value' }, { k : 'key2', v : 123 } ] })
db.test.insert({ point:[ 1, 10 ], tags : [ { k : 'key', v : 'value' } ] })

db.test.ensureIndex({ point : "2d" , "tags.k" : 1, "tags.v" : 1 })

// Succeeds, since should now lookup multi-keys correctly
assert(2 == db.test.find({ point : { $within : { $box : [[0,0],[12,12]] } } }).count(), "C")
// Succeeds, and should use geoindex
assert(2 == db.test.find({ point : [1, 10] }).count(), "D")
assert(2 == db.test.find({ point : [1, 10], "tags.v" : "value" }).count(), "E")
assert(1 == db.test.find({ point : [1, 10], "tags.v" : 123 }).count(), "F")

0 comments on commit 2cf0b20

Please sign in to comment.