Handle legacy coordinates as GeoJSON in minimongo (#2077) (#8620)

This commit is contained in:
mutdmour
2017-04-26 18:42:11 +03:00
committed by Ben Newman
parent c50cf4f49b
commit b7932ce9aa
2 changed files with 39 additions and 3 deletions

View File

@@ -3232,6 +3232,35 @@ Tinytest.add("minimongo - $near operator tests", function (test) {
handle.stop();
});
// issue #2077
Tinytest.add("minimongo - $near and $geometry for legacy coordinates", function(test){
var coll = new LocalCollection();
coll.insert({
loc: {
x: 1,
y: 1
}
});
coll.insert({
loc: [-1,-1]
});
coll.insert({
loc: [40,-10]
});
coll.insert({
loc: {
x: -10,
y: 40
}
});
test.equal(coll.find({ 'loc': { $near: [0, 0], $maxDistance: 4 } }).count(), 2);
test.equal(coll.find({ 'loc': { $near: {$geometry: {type: "Point", coordinates: [0, 0]}}} }).count(), 4);
test.equal(coll.find({ 'loc': { $near: {$geometry: {type: "Point", coordinates: [0, 0]}, $maxDistance:200000}}}).count(), 2);
});
// Regression test for #4377. Previously, "replace" updates didn't clone the
// argument.
Tinytest.add("minimongo - update should clone", function (test) {

View File

@@ -435,9 +435,10 @@ var VALUE_OPERATORS = {
throw Error("$near can't be inside another $ operator");
matcher._hasGeoQuery = true;
// There are two kinds of geodata in MongoDB: coordinate pairs and
// There are two kinds of geodata in MongoDB: legacy coordinate pairs and
// GeoJSON. They use different distance metrics, too. GeoJSON queries are
// marked with a $geometry property.
// marked with a $geometry property, though legacy coordinates can be
// matched using $geometry.
var maxDistance, point, distance;
if (isPlainObject(operand) && _.has(operand, '$geometry')) {
@@ -448,8 +449,11 @@ var VALUE_OPERATORS = {
// XXX: for now, we don't calculate the actual distance between, say,
// polygon and circle. If people care about this use-case it will get
// a priority.
if (!value || !value.type)
if (!value)
return null;
if(!value.type)
return GeoJSON.pointDistance(point,
{ type: "Point", coordinates: pointToArray(value) });
if (value.type === "Point") {
return GeoJSON.pointDistance(point, value);
} else {
@@ -481,6 +485,9 @@ var VALUE_OPERATORS = {
branchedValues = expandArraysInBranches(branchedValues);
var result = {result: false};
_.each(branchedValues, function (branch) {
if (!(typeof branch.value === "object")){
return;
}
var curDistance = distance(branch.value);
// Skip branches that aren't real points or are too far away.
if (curDistance === null || curDistance > maxDistance)