diff options
author | Greg Studer <greg@10gen.com> | 2013-05-15 09:50:08 -0400 |
---|---|---|
committer | Greg Studer <greg@10gen.com> | 2013-05-15 09:50:27 -0400 |
commit | f965235efa02833d8055013525ff0433567e0d95 (patch) | |
tree | adb71f539f1f2aba266e58b562126d0f255190cd | |
parent | f1f5a9538290d0a9e1831da34b70016a2774b40b (diff) | |
download | mongo-f965235efa02833d8055013525ff0433567e0d95.tar.gz |
SERVER-9647 don't transform 2dsphere desc fields into asc
-rw-r--r-- | jstests/geo_s2descindex.js | 65 | ||||
-rw-r--r-- | jstests/geo_s2validindex.js | 23 | ||||
-rw-r--r-- | src/mongo/db/index/s2_access_method.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/index/s2_near_cursor.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/index/s2_simple_cursor.cpp | 8 |
5 files changed, 110 insertions, 3 deletions
diff --git a/jstests/geo_s2descindex.js b/jstests/geo_s2descindex.js new file mode 100644 index 00000000000..215533392a0 --- /dev/null +++ b/jstests/geo_s2descindex.js @@ -0,0 +1,65 @@ +// +// Tests 2dsphere with descending fields, ensures correct lookup +// + +var coll = db.getCollection("twodspheredesc"); + +var descriptors = [["field1", -1], ["field2", -1], ["coordinates", "2dsphere"]] +var docA = {field1 : "a", field2 : 1, coordinates : [-118.2400013, 34.073893]} +var docB = {field1 : "b", field2 : 1, coordinates : [-118.2400012, 34.073894]} + +// Try both regular and near index cursors +var query = {coordinates : {$geoWithin : {$centerSphere : [[-118.240013, 34.073893], + 0.44915760491198753]}}}; +var queryNear = {coordinates : {$geoNear : {"type" : "Point", "coordinates" : [0, 0]}}}; + +// +// The idea here is we try "2dsphere" indexes in combination with descending +// other fields in various +// positions and ensure that we return correct results. +// + +for ( var t = 0; t < descriptors.length; t++) { + + var descriptor = {}; + for ( var i = 0; i < descriptors.length; i++) { + descriptor[descriptors[i][0]] = descriptors[i][1]; + } + + jsTest.log("Trying 2dsphere index with descriptor " + tojson(descriptor)); + + coll.drop(); + coll.ensureIndex(descriptor); + + coll.insert(docA); + coll.insert(docB); + + assert.eq(1, coll.count(Object.merge(query, {field1 : "a"}))); + assert.eq(1, coll.count(Object.merge(query, {field1 : "b"}))); + assert.eq(2, coll.count(Object.merge(query, {field2 : 1}))); + assert.eq(0, coll.count(Object.merge(query, {field2 : 0}))); + assert.eq(2, coll.count(queryNear)); + + var firstEls = descriptors.splice(1); + descriptors = firstEls.concat(descriptors); +} + +// +// Data taken from previously-hanging result +// + +jsTest.log("Trying case found in wild..."); + +coll.drop(); +coll.ensureIndex({coordinates : "2dsphere", field : -1}); +coll.insert({coordinates : [-118.240013, 34.073893]}); +var query = {coordinates : {$geoWithin : {$centerSphere : [[-118.240013, 34.073893], + 0.44915760491198753]}}, + field : 1}; + +assert.eq(null, coll.findOne(query)); +coll.remove({}) +coll.insert({coordinates : [-118.240013, 34.073893], field : 1}); +assert.neq(null, coll.findOne(query)); + +jsTest.log("Success!"); diff --git a/jstests/geo_s2validindex.js b/jstests/geo_s2validindex.js new file mode 100644 index 00000000000..af62119ad69 --- /dev/null +++ b/jstests/geo_s2validindex.js @@ -0,0 +1,23 @@ +// +// Tests valid cases for creation of 2dsphere index +// + +var coll = db.getCollection("twodspherevalid"); + +// Valid index +coll.drop(); +assert.eq(undefined, coll.ensureIndex({geo : "2dsphere", other : 1})); + +// Valid index +coll.drop(); +assert.eq(undefined, coll.ensureIndex({geo : "2dsphere", other : 1, geo2 : "2dsphere"})); + +// Invalid index, using hash with 2dsphere +coll.drop(); +assert.neq(undefined, coll.ensureIndex({geo : "2dsphere", other : "hash"}).err); + +// Invalid index, using 2d with 2dsphere +coll.drop(); +assert.neq(undefined, coll.ensureIndex({geo : "2dsphere", other : "2d"}).err); + +jsTest.log("Success!"); diff --git a/src/mongo/db/index/s2_access_method.cpp b/src/mongo/db/index/s2_access_method.cpp index ca4fc60d2c8..c43ecc75964 100644 --- a/src/mongo/db/index/s2_access_method.cpp +++ b/src/mongo/db/index/s2_access_method.cpp @@ -73,13 +73,20 @@ namespace mongo { _params.finestIndexedLevel >= _params.coarsestIndexedLevel); int geoFields = 0; + // Categorize the fields we're indexing and make sure we have a geo field. BSONObjIterator i(descriptor->keyPattern()); while (i.more()) { BSONElement e = i.next(); - if (e.type() == String && IndexNames::GEO_2DSPHERE == e.valuestr()) { + if (e.type() == String && IndexNames::GEO_2DSPHERE == e.String() ) { ++geoFields; } + else { + // We check for numeric in 2d, so that's the check here + uassert( 16823, (string)"Cannot use " + IndexNames::GEO_2DSPHERE + + " index with other special index types: " + e.toString(), + e.isNumber() ); + } } uassert(16750, "Expect at least one geo field, spec=" + descriptor->keyPattern().toString(), geoFields >= 1); diff --git a/src/mongo/db/index/s2_near_cursor.cpp b/src/mongo/db/index/s2_near_cursor.cpp index 780735e4b37..51bc07b75b2 100644 --- a/src/mongo/db/index/s2_near_cursor.cpp +++ b/src/mongo/db/index/s2_near_cursor.cpp @@ -51,7 +51,13 @@ namespace mongo { BSONObjIterator specIt(_descriptor->keyPattern()); while (specIt.more()) { BSONElement e = specIt.next(); - specBuilder.append(e.fieldName(), 1); + // Checked in AccessMethod already, so we know this spec has only numbers and 2dsphere + if ( e.type() == String ) { + specBuilder.append( e.fieldName(), 1 ); + } + else { + specBuilder.append( e.fieldName(), e.numberInt() ); + } } _specForFRV = specBuilder.obj(); diff --git a/src/mongo/db/index/s2_simple_cursor.cpp b/src/mongo/db/index/s2_simple_cursor.cpp index 25c88aa8f3f..3b3e988a908 100644 --- a/src/mongo/db/index/s2_simple_cursor.cpp +++ b/src/mongo/db/index/s2_simple_cursor.cpp @@ -46,7 +46,13 @@ namespace mongo { BSONObjIterator i(_descriptor->keyPattern()); while (i.more()) { BSONElement e = i.next(); - specBuilder.append(e.fieldName(), 1); + // Checked in AccessMethod already, so we know this spec has only numbers and 2dsphere + if ( e.type() == String ) { + specBuilder.append( e.fieldName(), 1 ); + } + else { + specBuilder.append( e.fieldName(), e.numberInt() ); + } } BSONObj spec = specBuilder.obj(); |