Mongodb – $nearSphere returns too many data. What am I missing? Am I wrong? Is it a bug? Does other see the same thing

mongodbspatial

I noticed that $near and $nearSphere returns completely different data and I got suspicious. After all, when latitude is near equator it sphere distance shouldn't differ a lot from euclidean distance.

db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.053980478460939611 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$all" : [/^soto/, /^nasi/] } }).limit(200);

It returns 48 data.

I'll attached it anyway

/* 0 */
{
  "_id" : "nasi-uduk-soto-ayam__-6.18_106.77",
  "BuildingID" : null,
  "Title" : "Nasi Uduk Soto Ayam",
  "InBuildingAddress" : null,
  "Building" : null,
  "Street" : "Jl. Panjang",
  "Districts" : [],
  "City" : "Jakarta",
  "Country" : "Indonesia",
  "LongitudeLatitudeFromGoogle" : null,
  "DistanceFromGoogleAddress" : 0.0,
  "Checkin" : 0,
  "Note" : null,
  "PeopleCount" : 0,
  "Prominent" : 45.5,
  "CountViews" : 0,
  "StreetAdditional" : null,
  "LongitudeLatitude" : {
    "Longitude" : 106.765673160553,
    "Latitude" : -6.17522230915668
  },
  "Rating" : {
    "Stars" : 0.0,
    "Weight" : 0.0
  },
  "CurrentlyWorkedURL" : null,
  "Reviews" : [],
  "ZIP" : null,
  "Tags" : ["Restaurant"],
  "Phones" : [],
  "Website" : null,
  "Email" : null,
  "Price" : null,
  "openingHour" : null,
  "Promotions" : [],
  "SomethingWrong" : false,
  "BizMenus" : [],
  "Brochures" : [],
  "Aliases" : [],
  "indexContents" : ["restaura", "estauran", "staurant", "taurant", "aurant", "urant", "rant", "ant", "nt", "t", "nasi", "asi", "si", "i", "uduk", "duk", "uk", "k", "soto", "oto", "to", "o", "ayam", "yam", "am", "m"]
}

/* 1 */
{
  "_id" : "nasi-soto-padang_pasar-slipi-jaya_-6.19_106.80",
  "BuildingID" : null,
  "Title" : "Nasi Soto Padang",
  "InBuildingAddress" : "Lt.1 Los Alas",
  "Building" : null,
  "Street" : "Jl.Kemanggisan Utama Raya",
  "Districts" : [],
  "City" : "Jakarta",
  "Country" : "Indonesia",
  "LongitudeLatitudeFromGoogle" : null,
  "DistanceFromGoogleAddress" : 0.0,
  "Checkin" : 0,
  "Note" : null,
  "PeopleCount" : 0,
  "Prominent" : 45.5,
  "CountViews" : 0,
  "StreetAdditional" : null,
  "LongitudeLatitude" : {
    "Longitude" : 106.79647564888,
    "Latitude" : -6.18998465381734
  },
  "Rating" : {
    "Stars" : 0.0,
    "Weight" : 0.0
  },
  "CurrentlyWorkedURL" : null,
  "Reviews" : [],
  "ZIP" : null,
  "Tags" : ["Restaurant"],
  "Phones" : [],
  "Website" : null,
  "Email" : null,
  "Price" : null,
  "openingHour" : null,
  "Promotions" : [],
  "SomethingWrong" : false,
  "BizMenus" : [],
  "Brochures" : [],
  "Aliases" : [],
  "indexContents" : ["restaura", "estauran", "staurant", "taurant", "aurant", "urant", "rant", "ant", "nt", "t", "nasi", "asi", "si", "i", "soto", "oto", "to", "o", "padang", "adang", "dang", "ang", "ng", "g"]
}

/* 47 */
{
  "_id" : "nasi-gandul__-7.43_109.24",
  "BuildingID" : null,
  "Title" : "Nasi Gandul",
  "InBuildingAddress" : null,
  "Building" : null,
  "Street" : "Jl. Brobahan Pr - 40 rt 004 Rw 004",
  "Districts" : [],
  "City" : "Purwokerto",
  "Country" : "Indonesia",
  "LongitudeLatitudeFromGoogle" : null,
  "DistanceFromGoogleAddress" : 0.0,
  "Checkin" : 0,
  "Note" : null,
  "PeopleCount" : 0,
  "Prominent" : 30.5,
  "CountViews" : 0,
  "StreetAdditional" : null,
  "LongitudeLatitude" : {
    "Longitude" : 109.239182174206,
    "Latitude" : -7.42585664273589
  },
  "Rating" : {
    "Stars" : 3.0,
    "Weight" : 1.0
  },
  "CurrentlyWorkedURL" : null,
  "Reviews" : [],
  "ZIP" : "53116",
  "Tags" : ["Angkringan", "Restaurant Indonesian", "Soto & Sop"],
  "Phones" : ["+62(281)7918181"],
  "Website" : null,
  "Email" : null,
  "Price" : null,
  "openingHour" : null,
  "Promotions" : [],
  "SomethingWrong" : false,
  "BizMenus" : [],
  "Brochures" : [],
  "Aliases" : [],
  "indexContents" : ["angkring", "ngkringa", "gkringan", "kringan", "ringan", "ingan", "ngan", "gan", "an", "n", "restaura", "estauran", "staurant", "taurant", "aurant", "urant", "rant", "ant", "nt", "t", "indonesi", "ndonesia", "donesian", "onesian", "nesian", "esian", "sian", "ian", "soto", "oto", "to", "o", "&", "sop", "op", "p", "nasi", "asi", "si", "i", "gandul", "andul", "ndul", "dul", "ul", "l"]
}

I put the data into excel and compute the distance using this formula

=SQRT(POWER(E2-$G$1,2)+POWER((F2-$H$1)*COS($H$1*PI()/180),2))

That one should greatly approximate spherical distance. Also notice that latitude is -6 which is not far from equator.

Here is the result

0.013516826
0.023857967
0.037658667
0.038737146
0.042414787
0.046725248
0.051006427
0.053567221
0.057448344
0.061592999
0.062329244
0.065276161
0.066035611
0.076251787
0.109671831
0.112097201
0.13417281
0.136471939
0.172293693
1.058802838
1.078123028
1.079160684
1.080954023
1.081148114
1.081099449
1.092061283
1.094281476
1.094431917
1.096845722
1.097063729
1.096953691
1.097201996
1.105389179
1.105442127
1.10839237
1.108717834
1.108840349
1.111636423
1.113187903
1.118767984
1.118767984
1.133952371
1.135077548
1.154967917
1.161142923
1.185994885
1.199509086
2.756884824

Here is the screenshot of my excel sheetenter image description here

Here is the actual excel

            106.772835  -6.186753
  "_id"      "nasi-uduk-soto-ayam__-6.18_106.77",   106.7656732 -6.175222309    0.013516826
  "_id"      "nasi-soto-padang_pasar-slipi-jaya_-6.19_106.80",  106.7964756 -6.189984654    0.023857967
  "_id"      "nasi-uduk-soto-ayam__-6.22_106.77",   106.7718959 -6.224620499    0.037658667
  "_id"      "nasi-campur-%26-soto-babat-kenanga_komp.-ruko-permata-senayan%2C_-6.22_106.79",   106.79199   -6.22062    0.038737146
  "_id"      "soto-mie-nasi_indomaret-(univ.-mercu-buana)_-6.21_106.74",    106.7379928 -6.211082144    0.042414787
  "_id"      "soto-kudus%2C-soto-ayam-%26amp%3B-nasi-pindang_plaza-senayan_-6.23_106.80",   106.7989969 -6.225694167    0.046725248
  "_id"      "soto-kudus%2C-soto-ayam-%26amp%3B-nasi-pindang_plaza-bri-ii_-6.22_106.81",    106.8136847 -6.217476287    0.051006427
  "_id"      "soto-kudus%2C-soto-ayam-%26amp%3B-nasi-pindang_automall-indonesia_-6.23_106.81",  106.8096431 -6.225898946    0.053567221
  "_id"      "soto-kudus%2C-soto-ayam-%26amp%3B-nasi-pindang_menara-mulia_-6.22_106.82",    106.81656   -6.224232983    0.057448344
  "_id"      "nasi-gule-gandaria__-6.24_106.80",    106.795285  -6.244444863    0.061592999
  "_id"      "nasi-soto-monggo-mampir__-6.24_106.80",   106.7971516 -6.244479441    0.062329244
  "_id"      "nasi-soto-ayam-\"pak-min\"__-6.24_106.82",    106.8151546 -6.236743573    0.065276161
  "_id"      "nasi-soto-ayam-pak-min---santa__-6.24_106.81",    106.812959  -6.239508   0.066035611
  "_id"      "soto-mie-nasi-bogor__-6.23_106.83",   106.8322349 -6.234845139    0.076251787
  "_id"      "nasi-uduk-soto-ayam__-6.24_106.87",   106.8693781 -6.239089942    0.109671831
  "_id"      "soto-ayam-%2F-nasi-uduk-betawi__-6.28_106.71",    106.714092  -6.282785   0.112097201
  "_id"      "soto-minang-roda-jaya_ruko-tongkol-indah_-6.12_106.89",   106.889044  -6.119294471    0.13417281
  "_id"      "nasi-bebek-dan-soto-mas-muchlis_summarecon-kelapa-gading_-6.16_106.91",   106.9059021 -6.156281135    0.136471939
  "_id"      "nasi-liwet-%26-soto-kwali-kalimalang__-6.25_106.93",  106.9338112 -6.248527508    0.172293693
  "_id"      "soto-ayam-nasi-rames__-6.88_107.58",  107.5751638 -6.881692483    1.058802838
  "_id"      "nasi-liwet-soto-solo_rumah-mode_-6.88_107.60",    107.5998616 -6.882452292    1.078123028
  "_id"      "nasi-soto-ayam-madura__-6.91_107.57", 107.5749707 -6.912900474    1.079160684
  "_id"      "nasi-soto-mie__-6.89_107.60", 107.5969434 -6.890355658    1.080954023
  "_id"      "nasi-rames-soto-bandung-enjoi__-6.89_107.60", 107.5970721 -6.890504777    1.081148114
  "_id"      "nasi-soto-ayam__-6.91_107.58",    107.5769877 -6.913560825    1.081099449
  "_id"      "nasi-soto-ayam__-6.91_107.60",    107.5977552 -6.90656    1.092061283
  "_id"      "nasi-soto-ayam-madura__-6.89_107.62", 107.6157832 -6.888615935    1.094281476
  "_id"      "nasi-goreng-soto-ayam__-6.90_107.61", 107.6093245 -6.89662571 1.094431917
  "_id"      "nasi-soto-gulai-kambing__-6.90_107.61",   107.6090455 -6.900715755    1.096845722
  "_id"      "putra-bengawan-nasi-goreng-%26-soto__-6.89_107.62",   107.617187  -6.891298   1.097063729
  "_id"      "nasi-soto-ayam__-6.90_107.61",    107.6088095 -6.901163102    1.096953691
  "_id"      "nasi-uduk-%26amp%3B-soto-kikil-cak-khohar__-6.89_107.61", 107.6144958 -6.894765295    1.097201996
  "_id"      "nasi-soto-ayam__-6.90_107.62",    107.6204395 -6.900453028    1.105389179
  "_id"      "nasi-goreng-soto-ayam__-6.90_107.62", 107.6206326 -6.900303912    1.105442127
  "_id"      "nasi-soto-ayam-madura__-6.91_107.62", 107.6169634 -6.909279174    1.10839237
  "_id"      "nasi-soto_pasar-baru_-6.92_107.61",   107.605226  -6.923423387    1.108717834
  "_id"      "nasi-soto-ayam-madura_pasar-baru_-6.92_107.61",   107.6053333 -6.92348729 1.108840349
  "_id"      "nasi-soto-sarinah__-6.90_107.63", 107.631175  -6.897282   1.111636423
  "_id"      "nasi-uduk-soto__-6.89_107.64",    107.6361465 -6.893636262    1.113187903
  "_id"      "nasi-soto-ayam-madura__-6.91_107.63", 107.629376  -6.910677   1.118767984
  "_id"      "nasi-soto-ayam__-6.91_107.63",    107.629376  -6.910677   1.118767984
  "_id"      "nasi-uduk-soto__-6.94_107.62",    107.6248813 -6.93937772 1.133952371
  "_id"      "nasi-soto-ayam-khas-madura__-6.94_107.63",    107.625749  -6.940099   1.135077548
  "_id"      "nasi-uduk-%26amp%3B-soto__-6.96_107.64",  107.638936  -6.955310213    1.154967917
  "_id"      "nasi-soto-ayam_ruko-metro-trade-center_-6.94_107.66", 107.6600504 -6.940208438    1.161142923
  "_id"      "nasi-soto-ayam-khas-madura__-6.94_107.69",    107.6948118 -6.937141164    1.185994885
  "_id"      "nasi-soto-ayam-khas-madura-cak-nonk__-6.93_107.72",   107.7156472 -6.932668019    1.199509086
  "_id"      "nasi-gandul__-7.43_109.24",   109.2391822 -7.425856643    2.756884824

Look again the term in the query

"$maxDistance" : 0.053980478460939611

Go figure.

Best Answer

You are seeing too many results for $nearSphere compared with $near because with spherical geometry operators (i.e. $nearSphere), you also need to convert the any distances used in the query (i.e. $maxDistance) to radians in order to get the right result. Here, it doesn't look like you converted $maxDistance to radians.

To convert from distance to radians, divide the distance by the radius of the earth. If you are using metric units, this would be 6378.137 km. If you are using imperial units, this would be: 3963.192 mi

Try the $nearSphere query again with $maxDistance converted to radians.