Mongodb агрегация или проекция - PullRequest
0 голосов
/ 18 декабря 2018

{
  "items": [
    {
      "id": "5bb619e49593e5d3cbaa0b52",
      "name": "Flowers",
      "weight": "1.5"
    },
    {
      "id": "5bb619e4ebdccb9218aa9dcb",
      "name": "Chair",
      "weight": "8.4"
    },
    {
      "id": "5bb619e4911037797edae511",
      "name": "TV",
      "weight": "20.8"
    },
    {
      "id": "5bb619e4504f248e1be543d3",
      "name": "Skateboard",
      "weight": "5.9"
    },
    {
      "id": "5bb619e40fee29e3aaf09759",
      "name": "Donald Trump statue",
      "weight": "18.4"
    },
    {
      "id": "5bb619e44251009d72e458b9",
      "name": "Molkkÿ game",
      "weight": "17.9"
    },
    {
      "id": "5bb619e439d3e99e2e25848d",
      "name": "Helmet",
      "weight": "22.7"
    }
  ]
}

У меня такая структура моделей.Я хочу рассчитать вес каждого заказа.Стоит ли использовать агрегацию или у кого-то есть идеи?

это пример заказа:

{
      "id": "5bb61dfd4d64747dd8d7d6cf",
      "date": "Sat Aug 11 2018 02:01:25 GMT+0000 (UTC)",
      "items": [
        {
          "item_id": "5bb619e44251009d72e458b9",
          "quantity": 4
        },
        {
          "item_id": "5bb619e4504f248e1be543d3",
          "quantity": 2
        },
        {
          "item_id": "5bb619e40fee29e3aaf09759",
          "quantity": 3
        }
      ]
    }

enter image description here

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Вы можете использовать ниже aggregation

db.order.aggregate([
  { "$unwind": "$items" },
  { "$lookup": {
    "from": "items",
    "localField": "items.item_id",
    "foreignField": "id",
    "as": "item"
  }},
  { "$unwind": "$item" },
  { "$addFields": { "items.weight": "$item.weight" }},
  { "$group": {
    "_id": "$_id",
    "items": { "$push": "$items" },
    "date": { "$first": "$date" }
  }}
])
0 голосов
/ 18 декабря 2018

У вас есть два варианта без изменения структуры вашей модели:

  1. извлечение всех элементов, используемых в Parcel, из базы данных в вашем приложении
  2. выполнение всех вычислений на стороне базы данных с использованием агрегирования(и $lookup)

Это очень зависит от вашей фактической модели данных и размера набора данных.Первый вариант очень прост и потенциально может быть более производительным для больших наборов данных, особенно при использовании набора шардинга / реплики.Но это требует большего количества обращений к базе данных, что приведет к большей задержке.С другой стороны, агрегация в некоторых случаях может быть довольно медленной при поиске.Но единственный хороший способ - проверить это на реальных данных.Если ваш текущий набор данных крошечный (скажем, 100 Мб), выберите удобный для вас способ - оба будут отлично работать.

Обновление

Поскольку вам нужно распределить Orders на Parcels, я бы предпочел перейти с вариантом № 1, хотя использование агрегации все еще возможно.

Вот что я бы сделал:

  1. извлечение Order из базы данных
  2. извлечение всех связанных Items из базы данных по идентификаторам, найденным в Order.items
  3. выполнить вычисление Order веса
  4. создать один Parcel, если вес <30, и сохранить его в базе данных </li>
  5. или, если вес> 30, распределить каким-либо образом ItemsParcels и сохраните их в базе данных

Обратите внимание, что вы можете получить несколько Items по их идентификаторам за один вызов с запросом, подобным следующему:

{
 _id: { $in: [<id1>, <id2>] }
}

Существует такжееще одна вещь, чтобы рассмотреть.Обратите внимание на тот факт, что MongoDB не имеет транзакций или атомарности нескольких документов.Таким образом, выполнение операций такого типа (извлечение чего-либо из БД, выполнение вычислений и сохранение обратно) со схемой, определяемой способом, который вы показываете, может привести к созданию дубликатов.

...