Производительность и масштабируемость Mongodb - PullRequest
1 голос
/ 08 октября 2019

Я пытаюсь оптимизировать для высокой масштабируемости мой запрос агрегации mongodb, но кое-что я не понимаю.

Я запускаю программное обеспечение на nodejs 10.x GoogleAppEngine и mongodb 3.6 на Atlas серверах M30.

У меня большая коллекция квартир (100 тыс., Но будет больше в ближайшем будущем), каждая квартира имеет свою собственную информациюо размере, расположении, ценах и многом другом, которые хранятся в одном вложенном документе (объект массива объекта массива)

Потому что мне нужно выполнить поиск в этой коллекции, чтобы найти особенности квартир и отсортировать ихПо расчетной цене я построил очень большой конвейер агрегации: почти 15 шагов с переменным $ lookup, $ map, $ сокращение для более чем 500 строк запроса .

Это всего лишь поток:


    $aggregation = [
      { $match: { $and: [
        { $geoWithin : '' }, 
        { field1: '' },
        { field2: '' },
        { fieldN: '' }    
      ]}},                   // Initial match 
      {$project: {}},          // pass just a subset of the fields
      {$addFields: {
       $map: {}       // first step of processing data
      }},
      {$addFields: {
       $map: {        // post processing previous data 
         $let: { $map: { $let: {} } }
       }},        
      },
      {$lookup: {}},     // 1th external collection to join
      {$lookup: {}},     // 2th external collection to join
      {$addFields: {}},  // appends 5 more calculated fields
      {$match : { $and:[
        {field1: ''},
        {field2: ''},
        {field3: ''},
      ] }},     // final match on processed data
      {$sort: {}},
      {$group: {}},
      {$project: {}}    // for limiting and paginating results
    ]

Кажется, все работает нормально, запрос отвечает примерно за 300 мс , и пользовательский опыт очень хороший, НО,вчера я начал делать некоторые тесты производительности, такие как отправка большого количества запросов параллельно с инструментом, и вылезла проблема! После первых 10 запросов база данных начинает ставить запросы в очередь, увеличивая время их ответа, пока оно не превысит 100 секунд для одного ответа, а затем перестанет отвечать!

  • Этоправильный подход или лучше сделать всю логику на сервере nodejs и позволить запросу вернуть все отфильтрованные, но не обработанные результаты?
  • Есть ли другой лучший подход?

Спасибо

1 Ответ

1 голос
/ 09 октября 2019

Кажется, я обнаружил, где проблема: сама структура данных!

Это фрагмент всего объекта квартиры:

{
_id: 
info: {},
pricing: {},
conditioons: {},
...
seasons: [{
  rules:{},
  pricing:{},
   conditions:{},
   ...
   ...,
  }   
  {},
  {},
  {},
  ...
 ]
}

Проблема в сезоны массив !! Увеличение его размера может поставить под угрозу внутренний механизм javascript mongodb.

Решением было переместить массив всех сезонов из объекта квартир в одну коллекцию , с соответствующим индексом и полем для ссылки. в их квартиру. В основном запросе агрегации используйте этап поиска $ с коллекцией сезонов, отфильтрованной так, чтобы привязывать только нужные времена года, которые будут 2 или 3 вместо 300!.

Это изменение показалось мне странным, но оноускорить выполнение запроса в 10-15 раз!

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...