MongoDB 3.4rc med 2 miljoner poster
Jag tror att problemet med din kod är relaterat till "query"-paramet, eftersom du gör en annan fråga på en samling utan ett index.
UPPDATERING (med resultat/statistik):
db.runCommand( { dropDatabase: 1 } )
db.createCollection("places");
db.places.createIndex( { "locs.loc.coordinates" : "2dsphere" } )
function randInt(n) { return parseInt(Math.random()*n); }
function randFloat(n) { return Math.random()*n; }
for(var j=0; j<10; j++) {
print("Building op "+j);
var bulkop=db.places.initializeOrderedBulkOp() ;
for (var i = 0; i < 1000000; ++i) {
bulkop.insert(
{
locs: [
{
loc : {
type: "Point",
coordinates: [ randFloat(180), randFloat(90) ]
}
},
{
loc : {
coordinates: [ randFloat(180), randFloat(90) ]
}
}
]
}
)
};
print("Executing op "+j);
bulkop.execute();
}
Det här är frågan:
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ 73.9667, 40.78 ] },
spherical: true
}
)
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ 73.9667, 40.78 ] },
spherical: true,
query: { category: "private" }
}
)
Efter att ha skapat "category"-index:{ locs.loc.coordinates:"2dsphere", kategori:1 }
UPPDATERING: genom att lägga till "maxDistance" kan du utföra 396ms vs 6863ms
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ 73.9667, 40.78 ] },
spherical: true,
query: {category: "private"},
maxDistance: 1000000
}
)
maxAvstånd:1000000
"stats" : {
"nscanned" : NumberInt(107820),
"objectsLoaded" : NumberInt(1),
"avgDistance" : 938598.1782650856,
"maxDistance" : 938598.1782650856,
"time" : NumberInt(396)
}
utan "maxDistance":
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ 73.9667, 40.78 ] },
spherical: true,
query: {category: "private"}
}
)
"stats" : {
"nscanned" : NumberInt(2023916),
"objectsLoaded" : NumberInt(6),
"avgDistance" : 3013587.205365039,
"maxDistance" : 4263919.742779636,
"time" : NumberInt(6863)
}
Källa:https://www.mongodb .com/blog/post/geospatial-performance-improvements-in-mongodb-3-2
Ännu mer använder din fråga "en array av koordinater" som jag tror är värdelös eftersom ett objekt (i allmänhet) har en geolokaliseringspunkt.
Ett annat sätt att optimera är att göra "geoWithin " eftersom sorterar inte efter "avstånd" (du kanske vill sortera efter "mest röstade restaurang"). Beroende på scenariot.