2016-10-24 1 views
0

Я пытаюсь использовать mongoDB в качестве поисковой системы и понимаю, что это катастрофа. я пытаюсь сделать простой запрос против 5 миллионов географических документов.как использовать mongoDB как поисковая система?

db.runCommand({ dropDatabase: 1 }) 

db.createCollection("places"); 

db.places.createIndex({ "locs.loc" : "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 : { 
       type: "Point", 
       coordinates: [ randFloat(180), randFloat(90) ] 
      } 
      } 
     ] 
     } 
    ) 
    }; 
    print("Executing op "+j); 
    bulkop.execute(); 
} 

, а затем я выполнить запрос, который не соответствует ни одного документа:

db.runCommand(
    { 
    geoNear: "places", 
    near: { type: "Point", coordinates: [ 73.9667, 40.78 ] }, 
    spherical: true, 
    query: { category: "xyz" } 
    } 
) 

это займет 4 минуты вернуться!

"waitedMS" : NumberLong(0), 
    "results" : [ ], 
    "stats" : { 
      "nscanned" : 10018218, 
      "objectsLoaded" : 15000000, 
      "maxDistance" : 0, 
      "time" : 219873 
    }, 
    "ok" : 1 

тот же запрос, сделанный в течение Exemple somethink как индекс сфинкс (использованному в самом деле нет индекса вообще для такого запроса, это просто прокрутить все reccord, которые уже в памяти, чтобы фильтровать их) возвращение в 200 мс

что я делаю неправильно? их 32 ГБ свободной памяти на компьютере, и все данные используют только 150 МБ. Это их способ ускорить работу mongoDB? или окончательно мы не можем использовать mongoDB в качестве поисковой системы?

+0

удалить «запрос», на моем компьютере я могу получить 6 мс на 1 млн. Записей. –

+0

{«nscanned»: 117, «objectsLoaded»: 59, «avgDistance»: 0.001017138667266944, «maxDistance»: 0.0016776194783600408, «время»: 2} –

+0

Daniele, спасибо, но цель в том, чтобы не удалить «запрос» :(потому что раньше, чтобы запускать запрос, вы не знаете, будет ли он соответствовать некоторым записям или нет ... здесь идея заключалась в том, чтобы моделировать запрос, который возвращает нет (или очень мало) записей. и 4 мин, чтобы увидеть, что они не соответствуют запись не принимается – loki

ответ

4

MongoDB 3.4rc с 2 млн записей

Я думаю, что проблема с кодом связана с «запросом» парам, потому что вы делаете еще один запрос на коллекции без индекса.

ОБНОВЛЕНИЕ (с результатами/статистике):

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(); 
} 

Collection (i have more object, since i run the script more then once

Это запрос:

db.runCommand(
    { 
    geoNear: "places", 
    near: { type: "Point", coordinates: [ 73.9667, 40.78 ] }, 
    spherical: true 
    } 
) 

58ms: enter image description here

2мс второй прогон: enter image description here

db.runCommand(
    { 
    geoNear: "places", 
    near: { type: "Point", coordinates: [ 73.9667, 40.78 ] }, 
    spherical: true, 
    query: { category: "private" } 
    } 
) 

156996ms: enter image description here

После создания "категории" индекс: {locs.loc.координаты: "2dsphere", категория: 1}

13562ms: enter image description here

UPDATE: путем добавления "maxDistance" вы можете выполнить 396ms против 6863ms

db.runCommand(
    { 
    geoNear: "places", 
    near: { type: "Point", coordinates: [ 73.9667, 40.78 ] }, 
    spherical: true, 
    query: {category: "private"}, 
    maxDistance: 1000000 
    } 
) 

maxDistance: 1000000

"stats" : { 
    "nscanned" : NumberInt(107820), 
    "objectsLoaded" : NumberInt(1), 
    "avgDistance" : 938598.1782650856, 
    "maxDistance" : 938598.1782650856, 
    "time" : NumberInt(396) 
} 

без "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) 
} 

Источник: https://www.mongodb.com/blog/post/geospatial-performance-improvements-in-mongodb-3-2

Даже больше ваш запрос использует "массив координат", что я думаю, что это бесполезно, так как один объект (обычно) имеет 1 геолокационная точка.

Другой способ оптимизации - «geoWithin», так как не сортируется по «расстоянию» (возможно, вы хотите отсортировать по «большинству проголосовавших ресторанов»). В зависимости от сценария.

+0

просто см. мой предыдущий комментарий, цель в том, чтобы не удалить «запрос» :(потому что перед тем, как запускать запрос, вы не знаете, будет ли он соответствовать некоторым записям или нет. .. здесь идея заключалась в том, чтобы смоделировать запрос, который возвращает нет (или очень мало) записей. и 4 мин, чтобы увидеть, что их несоответствующая запись неприемлема. – loki

+0

у вас должен быть индекс –

+0

, но я не могу dd по всем возможным запросам! на sphinx их нет индекса, и требуется 200 мс для возврата – loki

Смежные вопросы