Агрегация $ group приводит к ошибке размера BSONobj (должно быть меньше 16 МБ) - PullRequest
0 голосов
/ 09 сентября 2018

У меня очень большой набор данных о людях, который был импортирован в следующую схему:

_id, personId, city, street, streetNo

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

{
    "_id": "$_id", 
    "personId": "$personId",
    "Address": {
        "city": "$city", 
        "street": "$street",
        "streetNo": "$streetNo"
    }
}

Эта первая часть завершается мгновенно.

Теперь проблема в том, что у каждого человека может быть несколько адресов. Я хочу сгруппировать адреса в одно лицо по personId:

{
  _id: "$personId",
  Addresses: {
    $addToSet: "$Address"
  }
}

Я знаю, что этот запрос действителен, и он работает. Но когда я запускаю запрос, через пару минут я получаю слишком большую ошибку BSONobj. Это потому, что у человека слишком много адресов, делающих документ слишком большим? Или набор данных слишком большой? Как я могу обойти эту ошибку?

1 Ответ

0 голосов
/ 09 сентября 2018

Пожалуйста, ознакомьтесь с документацией MongoDB .Обратите особое внимание на следующее:

При возврате курсора или сохранении результатов в коллекции на каждый документ в наборе результатов распространяется ограничение размера документа BSON, в настоящее время 16 мегабайт;если какой-либо документ, который превышает ограничение размера документа BSON, команда выдаст ошибку.

, а также:

Стадии конвейера имеют ограничение в 100 мегабайтБАРАН.Если этап превышает этот предел, MongoDB выдаст ошибку.

Таким образом, мы можем заключить, что с ошибкой, отмечающей ограничение в 16 МБ, вы превышаете ограничение размера документа.Ваша оценка того, что у человека слишком много адресов, является правильной.

К сожалению, мало что можно порекомендовать, не зная, как выглядят ваши данные, или полный вызов конвейера агрегации.При этом, вот что я бы сделал:

  1. Попробуйте выполнить группировку, где вместо добавления адресов в набор вы получаете сумму количества адресов, связанных с человеком, например, {$group: {_id: "$personId", total: {$sum: 1}}.
  2. Сортировка документов по количеству, чтобы вы могли увидеть, какие из них наиболее проблемные, например, {$sort: {total: -1}}.
  3. Выберите один из проблемных документов и выполните поиск документов с помощью personIdсопоставление с документом _id.
  4. Выполните обычное подсчет всех документов, связанных с этим человеком, то есть db.your_collection.find({personId: ...}).count(), и сравните это значение с подсчетом из вашей агрегации.
  5. Если эти подсчетыаналогично (и особенно если они одинаковые), внимательно посмотрите на адреса, связанные с этим человеком, и попытайтесь найти причину, по которой набор Addresses становится таким большим.
  6. Если ввсе возможно, оптимизировать на основе ваших выводов.
...