Агрегация или проекция Mongodb

{
  "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
        }
      ]
    }

Агрегация или проекция Mongodb

Не могли бы вы опубликовать образец json-документа и вывод

Ashh 18.12.2018 17:16

Я опубликовал json всех товаров и пример одного заказа. для вывода я просто хочу знать вес каждого заказа, поэтому я могу добавить вес атрибута в схему заказа.

wassa 18.12.2018 17:34
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
67
2

Ответы 2

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

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

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

Обновлять

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

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

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

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

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

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

Спасибо за ответ, но не могли бы вы объяснить больше? У меня есть только json товаров и заказов, а затем я буду делать каждый заказ в одной или нескольких посылках, вес которых <= 30 кг

wassa 18.12.2018 17:34

Вы можете использовать ниже 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" }
  }}
])

Другие вопросы по теме